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

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

Issue 1969423002: [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/mips64/full-codegen-mips64.cc ('k') | src/heap/heap.h » ('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_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 // Possibly allocate a local context. 159 // Possibly allocate a local context.
160 if (info->scope()->num_heap_slots() > 0) { 160 if (info->scope()->num_heap_slots() > 0) {
161 Comment cmnt(masm_, "[ Allocate context"); 161 Comment cmnt(masm_, "[ Allocate context");
162 bool need_write_barrier = true; 162 bool need_write_barrier = true;
163 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 163 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
164 // Argument to NewContext is the function, which is still in rdi. 164 // Argument to NewContext is the function, which is still in rdi.
165 if (info->scope()->is_script_scope()) { 165 if (info->scope()->is_script_scope()) {
166 __ Push(rdi); 166 __ Push(rdi);
167 __ Push(info->scope()->GetScopeInfo(info->isolate())); 167 __ Push(info->scope()->GetScopeInfo(info->isolate()));
168 __ CallRuntime(Runtime::kNewScriptContext); 168 __ CallRuntime(Runtime::kNewScriptContext);
169 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 169 PrepareForBailoutForId(BailoutId::ScriptContext(),
170 BailoutState::TOS_REGISTER);
170 // The new target value is not used, clobbering is safe. 171 // The new target value is not used, clobbering is safe.
171 DCHECK_NULL(info->scope()->new_target_var()); 172 DCHECK_NULL(info->scope()->new_target_var());
172 } else { 173 } else {
173 if (info->scope()->new_target_var() != nullptr) { 174 if (info->scope()->new_target_var() != nullptr) {
174 __ Push(rdx); // Preserve new target. 175 __ Push(rdx); // Preserve new target.
175 } 176 }
176 if (slots <= FastNewContextStub::kMaximumSlots) { 177 if (slots <= FastNewContextStub::kMaximumSlots) {
177 FastNewContextStub stub(isolate(), slots); 178 FastNewContextStub stub(isolate(), slots);
178 __ CallStub(&stub); 179 __ CallStub(&stub);
179 // Result of FastNewContextStub is always in new space. 180 // Result of FastNewContextStub is always in new space.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 __ Abort(kExpectedNewSpaceObject); 216 __ Abort(kExpectedNewSpaceObject);
216 __ bind(&done); 217 __ bind(&done);
217 } 218 }
218 } 219 }
219 } 220 }
220 } 221 }
221 222
222 // Register holding this function and new target are both trashed in case we 223 // Register holding this function and new target are both trashed in case we
223 // bailout here. But since that can happen only when new target is not used 224 // bailout here. But since that can happen only when new target is not used
224 // and we allocate a context, the value of |function_in_register| is correct. 225 // and we allocate a context, the value of |function_in_register| is correct.
225 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); 226 PrepareForBailoutForId(BailoutId::FunctionContext(),
227 BailoutState::NO_REGISTERS);
226 228
227 // Possibly set up a local binding to the this function which is used in 229 // Possibly set up a local binding to the this function which is used in
228 // derived constructors with super calls. 230 // derived constructors with super calls.
229 Variable* this_function_var = scope()->this_function_var(); 231 Variable* this_function_var = scope()->this_function_var();
230 if (this_function_var != nullptr) { 232 if (this_function_var != nullptr) {
231 Comment cmnt(masm_, "[ This function"); 233 Comment cmnt(masm_, "[ This function");
232 if (!function_in_register) { 234 if (!function_in_register) {
233 __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 235 __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
234 // The write barrier clobbers register again, keep it marked as such. 236 // The write barrier clobbers register again, keep it marked as such.
235 } 237 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 281
280 SetVar(arguments, rax, rbx, rdx); 282 SetVar(arguments, rax, rbx, rdx);
281 } 283 }
282 284
283 if (FLAG_trace) { 285 if (FLAG_trace) {
284 __ CallRuntime(Runtime::kTraceEnter); 286 __ CallRuntime(Runtime::kTraceEnter);
285 } 287 }
286 288
287 // Visit the declarations and body unless there is an illegal 289 // Visit the declarations and body unless there is an illegal
288 // redeclaration. 290 // redeclaration.
289 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 291 PrepareForBailoutForId(BailoutId::FunctionEntry(),
292 BailoutState::NO_REGISTERS);
290 { 293 {
291 Comment cmnt(masm_, "[ Declarations"); 294 Comment cmnt(masm_, "[ Declarations");
292 VisitDeclarations(scope()->declarations()); 295 VisitDeclarations(scope()->declarations());
293 } 296 }
294 297
295 // Assert that the declarations do not use ICs. Otherwise the debugger 298 // Assert that the declarations do not use ICs. Otherwise the debugger
296 // won't be able to redirect a PC at an IC to the correct IC in newly 299 // won't be able to redirect a PC at an IC to the correct IC in newly
297 // recompiled code. 300 // recompiled code.
298 DCHECK_EQ(0, ic_total_count_); 301 DCHECK_EQ(0, ic_total_count_);
299 302
300 { 303 {
301 Comment cmnt(masm_, "[ Stack check"); 304 Comment cmnt(masm_, "[ Stack check");
302 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 305 PrepareForBailoutForId(BailoutId::Declarations(),
306 BailoutState::NO_REGISTERS);
303 Label ok; 307 Label ok;
304 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 308 __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
305 __ j(above_equal, &ok, Label::kNear); 309 __ j(above_equal, &ok, Label::kNear);
306 __ call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET); 310 __ call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
307 __ bind(&ok); 311 __ bind(&ok);
308 } 312 }
309 313
310 { 314 {
311 Comment cmnt(masm_, "[ Body"); 315 Comment cmnt(masm_, "[ Body");
312 DCHECK(loop_depth() == 0); 316 DCHECK(loop_depth() == 0);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 369
366 // Record a mapping of this PC offset to the OSR id. This is used to find 370 // Record a mapping of this PC offset to the OSR id. This is used to find
367 // the AST id from the unoptimized code in order to use it as a key into 371 // the AST id from the unoptimized code in order to use it as a key into
368 // the deoptimization input data found in the optimized code. 372 // the deoptimization input data found in the optimized code.
369 RecordBackEdge(stmt->OsrEntryId()); 373 RecordBackEdge(stmt->OsrEntryId());
370 374
371 EmitProfilingCounterReset(); 375 EmitProfilingCounterReset();
372 } 376 }
373 __ bind(&ok); 377 __ bind(&ok);
374 378
375 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 379 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
376 // Record a mapping of the OSR id to this PC. This is used if the OSR 380 // Record a mapping of the OSR id to this PC. This is used if the OSR
377 // entry becomes the target of a bailout. We don't expect it to be, but 381 // entry becomes the target of a bailout. We don't expect it to be, but
378 // we want it to work if it is. 382 // we want it to work if it is.
379 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); 383 PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS);
380 } 384 }
381 385
382 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( 386 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
383 bool is_tail_call) { 387 bool is_tail_call) {
384 // Pretend that the exit is a backwards jump to the entry. 388 // Pretend that the exit is a backwards jump to the entry.
385 int weight = 1; 389 int weight = 1;
386 if (info_->ShouldSelfOptimize()) { 390 if (info_->ShouldSelfOptimize()) {
387 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 391 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
388 } else { 392 } else {
389 int distance = masm_->pc_offset(); 393 int distance = masm_->pc_offset();
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 bool should_normalize, 689 bool should_normalize,
686 Label* if_true, 690 Label* if_true,
687 Label* if_false) { 691 Label* if_false) {
688 // Only prepare for bailouts before splits if we're in a test 692 // Only prepare for bailouts before splits if we're in a test
689 // context. Otherwise, we let the Visit function deal with the 693 // context. Otherwise, we let the Visit function deal with the
690 // preparation to avoid preparing with the same AST id twice. 694 // preparation to avoid preparing with the same AST id twice.
691 if (!context()->IsTest()) return; 695 if (!context()->IsTest()) return;
692 696
693 Label skip; 697 Label skip;
694 if (should_normalize) __ jmp(&skip, Label::kNear); 698 if (should_normalize) __ jmp(&skip, Label::kNear);
695 PrepareForBailout(expr, TOS_REG); 699 PrepareForBailout(expr, BailoutState::TOS_REGISTER);
696 if (should_normalize) { 700 if (should_normalize) {
697 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 701 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
698 Split(equal, if_true, if_false, NULL); 702 Split(equal, if_true, if_false, NULL);
699 __ bind(&skip); 703 __ bind(&skip);
700 } 704 }
701 } 705 }
702 706
703 707
704 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 708 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
705 // The variable in the declaration always resides in the current context. 709 // The variable in the declaration always resides in the current context.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 } 745 }
742 break; 746 break;
743 747
744 case VariableLocation::CONTEXT: 748 case VariableLocation::CONTEXT:
745 if (hole_init) { 749 if (hole_init) {
746 Comment cmnt(masm_, "[ VariableDeclaration"); 750 Comment cmnt(masm_, "[ VariableDeclaration");
747 EmitDebugCheckDeclarationContext(variable); 751 EmitDebugCheckDeclarationContext(variable);
748 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 752 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
749 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister); 753 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister);
750 // No write barrier since the hole value is in old space. 754 // No write barrier since the hole value is in old space.
751 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 755 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
752 } 756 }
753 break; 757 break;
754 758
755 case VariableLocation::LOOKUP: { 759 case VariableLocation::LOOKUP: {
756 Comment cmnt(masm_, "[ VariableDeclaration"); 760 Comment cmnt(masm_, "[ VariableDeclaration");
757 __ Push(variable->name()); 761 __ Push(variable->name());
758 // Declaration nodes are always introduced in one of four modes. 762 // Declaration nodes are always introduced in one of four modes.
759 DCHECK(IsDeclaredVariableMode(mode)); 763 DCHECK(IsDeclaredVariableMode(mode));
760 // Push initial value, if any. 764 // Push initial value, if any.
761 // Note: For variables we must not push an initial value (such as 765 // Note: For variables we must not push an initial value (such as
762 // 'undefined') because we may have a (legal) redeclaration and we 766 // 'undefined') because we may have a (legal) redeclaration and we
763 // must not destroy the current value. 767 // must not destroy the current value.
764 if (hole_init) { 768 if (hole_init) {
765 __ PushRoot(Heap::kTheHoleValueRootIndex); 769 __ PushRoot(Heap::kTheHoleValueRootIndex);
766 } else { 770 } else {
767 __ Push(Smi::FromInt(0)); // Indicates no initial value. 771 __ Push(Smi::FromInt(0)); // Indicates no initial value.
768 } 772 }
769 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 773 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
770 __ CallRuntime(Runtime::kDeclareLookupSlot); 774 __ CallRuntime(Runtime::kDeclareLookupSlot);
771 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 775 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
772 break; 776 break;
773 } 777 }
774 } 778 }
775 } 779 }
776 780
777 781
778 void FullCodeGenerator::VisitFunctionDeclaration( 782 void FullCodeGenerator::VisitFunctionDeclaration(
779 FunctionDeclaration* declaration) { 783 FunctionDeclaration* declaration) {
780 VariableProxy* proxy = declaration->proxy(); 784 VariableProxy* proxy = declaration->proxy();
781 Variable* variable = proxy->var(); 785 Variable* variable = proxy->var();
(...skipping 24 matching lines...) Expand all
806 __ movp(ContextOperand(rsi, variable->index()), result_register()); 810 __ movp(ContextOperand(rsi, variable->index()), result_register());
807 int offset = Context::SlotOffset(variable->index()); 811 int offset = Context::SlotOffset(variable->index());
808 // We know that we have written a function, which is not a smi. 812 // We know that we have written a function, which is not a smi.
809 __ RecordWriteContextSlot(rsi, 813 __ RecordWriteContextSlot(rsi,
810 offset, 814 offset,
811 result_register(), 815 result_register(),
812 rcx, 816 rcx,
813 kDontSaveFPRegs, 817 kDontSaveFPRegs,
814 EMIT_REMEMBERED_SET, 818 EMIT_REMEMBERED_SET,
815 OMIT_SMI_CHECK); 819 OMIT_SMI_CHECK);
816 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 820 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
817 break; 821 break;
818 } 822 }
819 823
820 case VariableLocation::LOOKUP: { 824 case VariableLocation::LOOKUP: {
821 Comment cmnt(masm_, "[ FunctionDeclaration"); 825 Comment cmnt(masm_, "[ FunctionDeclaration");
822 PushOperand(variable->name()); 826 PushOperand(variable->name());
823 VisitForStackValue(declaration->fun()); 827 VisitForStackValue(declaration->fun());
824 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); 828 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
825 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); 829 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
826 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 830 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
827 break; 831 break;
828 } 832 }
829 } 833 }
830 } 834 }
831 835
832 836
833 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 837 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
834 // Call the runtime to declare the globals. 838 // Call the runtime to declare the globals.
835 __ Push(pairs); 839 __ Push(pairs);
836 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 840 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 10 matching lines...) Expand all
847 } 851 }
848 852
849 853
850 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 854 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
851 Comment cmnt(masm_, "[ SwitchStatement"); 855 Comment cmnt(masm_, "[ SwitchStatement");
852 Breakable nested_statement(this, stmt); 856 Breakable nested_statement(this, stmt);
853 SetStatementPosition(stmt); 857 SetStatementPosition(stmt);
854 858
855 // Keep the switch value on the stack until a case matches. 859 // Keep the switch value on the stack until a case matches.
856 VisitForStackValue(stmt->tag()); 860 VisitForStackValue(stmt->tag());
857 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 861 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
858 862
859 ZoneList<CaseClause*>* clauses = stmt->cases(); 863 ZoneList<CaseClause*>* clauses = stmt->cases();
860 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 864 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
861 865
862 Label next_test; // Recycled for each test. 866 Label next_test; // Recycled for each test.
863 // Compile all the tests with branches to their bodies. 867 // Compile all the tests with branches to their bodies.
864 for (int i = 0; i < clauses->length(); i++) { 868 for (int i = 0; i < clauses->length(); i++) {
865 CaseClause* clause = clauses->at(i); 869 CaseClause* clause = clauses->at(i);
866 clause->body_target()->Unuse(); 870 clause->body_target()->Unuse();
867 871
(...skipping 29 matching lines...) Expand all
897 901
898 // Record position before stub call for type feedback. 902 // Record position before stub call for type feedback.
899 SetExpressionPosition(clause); 903 SetExpressionPosition(clause);
900 Handle<Code> ic = 904 Handle<Code> ic =
901 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); 905 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
902 CallIC(ic, clause->CompareId()); 906 CallIC(ic, clause->CompareId());
903 patch_site.EmitPatchInfo(); 907 patch_site.EmitPatchInfo();
904 908
905 Label skip; 909 Label skip;
906 __ jmp(&skip, Label::kNear); 910 __ jmp(&skip, Label::kNear);
907 PrepareForBailout(clause, TOS_REG); 911 PrepareForBailout(clause, BailoutState::TOS_REGISTER);
908 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 912 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
909 __ j(not_equal, &next_test); 913 __ j(not_equal, &next_test);
910 __ Drop(1); 914 __ Drop(1);
911 __ jmp(clause->body_target()); 915 __ jmp(clause->body_target());
912 __ bind(&skip); 916 __ bind(&skip);
913 917
914 __ testp(rax, rax); 918 __ testp(rax, rax);
915 __ j(not_equal, &next_test); 919 __ j(not_equal, &next_test);
916 __ Drop(1); // Switch value is no longer needed. 920 __ Drop(1); // Switch value is no longer needed.
917 __ jmp(clause->body_target()); 921 __ jmp(clause->body_target());
918 } 922 }
919 923
920 // Discard the test value and jump to the default if present, otherwise to 924 // Discard the test value and jump to the default if present, otherwise to
921 // the end of the statement. 925 // the end of the statement.
922 __ bind(&next_test); 926 __ bind(&next_test);
923 DropOperands(1); // Switch value is no longer needed. 927 DropOperands(1); // Switch value is no longer needed.
924 if (default_clause == NULL) { 928 if (default_clause == NULL) {
925 __ jmp(nested_statement.break_label()); 929 __ jmp(nested_statement.break_label());
926 } else { 930 } else {
927 __ jmp(default_clause->body_target()); 931 __ jmp(default_clause->body_target());
928 } 932 }
929 933
930 // Compile all the case bodies. 934 // Compile all the case bodies.
931 for (int i = 0; i < clauses->length(); i++) { 935 for (int i = 0; i < clauses->length(); i++) {
932 Comment cmnt(masm_, "[ Case body"); 936 Comment cmnt(masm_, "[ Case body");
933 CaseClause* clause = clauses->at(i); 937 CaseClause* clause = clauses->at(i);
934 __ bind(clause->body_target()); 938 __ bind(clause->body_target());
935 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 939 PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS);
936 VisitStatements(clause->statements()); 940 VisitStatements(clause->statements());
937 } 941 }
938 942
939 __ bind(nested_statement.break_label()); 943 __ bind(nested_statement.break_label());
940 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 944 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
941 } 945 }
942 946
943 947
944 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 948 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
945 Comment cmnt(masm_, "[ ForInStatement"); 949 Comment cmnt(masm_, "[ ForInStatement");
946 SetStatementPosition(stmt, SKIP_BREAK); 950 SetStatementPosition(stmt, SKIP_BREAK);
947 951
948 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 952 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
949 953
950 // Get the object to enumerate over. 954 // Get the object to enumerate over.
(...skipping 12 matching lines...) Expand all
963 __ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rcx); 967 __ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rcx);
964 __ j(above_equal, &done_convert, Label::kNear); 968 __ j(above_equal, &done_convert, Label::kNear);
965 __ CompareRoot(rax, Heap::kNullValueRootIndex); 969 __ CompareRoot(rax, Heap::kNullValueRootIndex);
966 __ j(equal, &exit); 970 __ j(equal, &exit);
967 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 971 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
968 __ j(equal, &exit); 972 __ j(equal, &exit);
969 __ bind(&convert); 973 __ bind(&convert);
970 ToObjectStub stub(isolate()); 974 ToObjectStub stub(isolate());
971 __ CallStub(&stub); 975 __ CallStub(&stub);
972 __ bind(&done_convert); 976 __ bind(&done_convert);
973 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); 977 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
974 __ Push(rax); 978 __ Push(rax);
975 979
976 // Check cache validity in generated code. If we cannot guarantee cache 980 // Check cache validity in generated code. If we cannot guarantee cache
977 // validity, call the runtime system to check cache validity or get the 981 // validity, call the runtime system to check cache validity or get the
978 // property names in a fixed array. Note: Proxies never have an enum cache, 982 // property names in a fixed array. Note: Proxies never have an enum cache,
979 // so will always take the slow path. 983 // so will always take the slow path.
980 Label call_runtime; 984 Label call_runtime;
981 __ CheckEnumCache(&call_runtime); 985 __ CheckEnumCache(&call_runtime);
982 986
983 // The enum cache is valid. Load the map of the object being 987 // The enum cache is valid. Load the map of the object being
984 // iterated over and use the cache for the iteration. 988 // iterated over and use the cache for the iteration.
985 Label use_cache; 989 Label use_cache;
986 __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); 990 __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset));
987 __ jmp(&use_cache, Label::kNear); 991 __ jmp(&use_cache, Label::kNear);
988 992
989 // Get the set of properties to enumerate. 993 // Get the set of properties to enumerate.
990 __ bind(&call_runtime); 994 __ bind(&call_runtime);
991 __ Push(rax); // Duplicate the enumerable object on the stack. 995 __ Push(rax); // Duplicate the enumerable object on the stack.
992 __ CallRuntime(Runtime::kForInEnumerate); 996 __ CallRuntime(Runtime::kForInEnumerate);
993 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 997 PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER);
994 998
995 // If we got a map from the runtime call, we can do a fast 999 // If we got a map from the runtime call, we can do a fast
996 // modification check. Otherwise, we got a fixed array, and we have 1000 // modification check. Otherwise, we got a fixed array, and we have
997 // to do a slow check. 1001 // to do a slow check.
998 Label fixed_array; 1002 Label fixed_array;
999 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), 1003 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
1000 Heap::kMetaMapRootIndex); 1004 Heap::kMetaMapRootIndex);
1001 __ j(not_equal, &fixed_array); 1005 __ j(not_equal, &fixed_array);
1002 1006
1003 // We got a map in register rax. Get the enumeration cache from it. 1007 // We got a map in register rax. Get the enumeration cache from it.
(...skipping 21 matching lines...) Expand all
1025 __ jmp(&exit); 1029 __ jmp(&exit);
1026 1030
1027 // We got a fixed array in register rax. Iterate through that. 1031 // We got a fixed array in register rax. Iterate through that.
1028 __ bind(&fixed_array); 1032 __ bind(&fixed_array);
1029 1033
1030 __ movp(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object 1034 __ movp(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object
1031 __ Push(Smi::FromInt(1)); // Smi(1) indicates slow check 1035 __ Push(Smi::FromInt(1)); // Smi(1) indicates slow check
1032 __ Push(rax); // Array 1036 __ Push(rax); // Array
1033 __ movp(rax, FieldOperand(rax, FixedArray::kLengthOffset)); 1037 __ movp(rax, FieldOperand(rax, FixedArray::kLengthOffset));
1034 __ Push(rax); // Fixed array length (as smi). 1038 __ Push(rax); // Fixed array length (as smi).
1035 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); 1039 PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS);
1036 __ Push(Smi::FromInt(0)); // Initial index. 1040 __ Push(Smi::FromInt(0)); // Initial index.
1037 1041
1038 // Generate code for doing the condition check. 1042 // Generate code for doing the condition check.
1039 __ bind(&loop); 1043 __ bind(&loop);
1040 SetExpressionAsStatementPosition(stmt->each()); 1044 SetExpressionAsStatementPosition(stmt->each());
1041 1045
1042 __ movp(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index. 1046 __ movp(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index.
1043 __ cmpp(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length. 1047 __ cmpp(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length.
1044 __ j(above_equal, loop_statement.break_label()); 1048 __ j(above_equal, loop_statement.break_label());
1045 1049
(...skipping 21 matching lines...) Expand all
1067 __ EmitLoadTypeFeedbackVector(rdx); 1071 __ EmitLoadTypeFeedbackVector(rdx);
1068 __ Move(FieldOperand(rdx, FixedArray::OffsetOfElementAt(vector_index)), 1072 __ Move(FieldOperand(rdx, FixedArray::OffsetOfElementAt(vector_index)),
1069 TypeFeedbackVector::MegamorphicSentinel(isolate())); 1073 TypeFeedbackVector::MegamorphicSentinel(isolate()));
1070 1074
1071 // Convert the entry to a string or null if it isn't a property 1075 // Convert the entry to a string or null if it isn't a property
1072 // anymore. If the property has been removed while iterating, we 1076 // anymore. If the property has been removed while iterating, we
1073 // just skip it. 1077 // just skip it.
1074 __ Push(rcx); // Enumerable. 1078 __ Push(rcx); // Enumerable.
1075 __ Push(rbx); // Current entry. 1079 __ Push(rbx); // Current entry.
1076 __ CallRuntime(Runtime::kForInFilter); 1080 __ CallRuntime(Runtime::kForInFilter);
1077 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1081 PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
1078 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 1082 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
1079 __ j(equal, loop_statement.continue_label()); 1083 __ j(equal, loop_statement.continue_label());
1080 __ movp(rbx, rax); 1084 __ movp(rbx, rax);
1081 1085
1082 // Update the 'each' property or variable from the possibly filtered 1086 // Update the 'each' property or variable from the possibly filtered
1083 // entry in register rbx. 1087 // entry in register rbx.
1084 __ bind(&update_each); 1088 __ bind(&update_each);
1085 __ movp(result_register(), rbx); 1089 __ movp(result_register(), rbx);
1086 // Perform the assignment as if via '='. 1090 // Perform the assignment as if via '='.
1087 { EffectContext context(this); 1091 { EffectContext context(this);
1088 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1092 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1089 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); 1093 PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS);
1090 } 1094 }
1091 1095
1092 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). 1096 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
1093 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1097 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
1094 // Generate code for the body of the loop. 1098 // Generate code for the body of the loop.
1095 Visit(stmt->body()); 1099 Visit(stmt->body());
1096 1100
1097 // Generate code for going to the next element by incrementing the 1101 // Generate code for going to the next element by incrementing the
1098 // index (smi) stored on top of the stack. 1102 // index (smi) stored on top of the stack.
1099 __ bind(loop_statement.continue_label()); 1103 __ bind(loop_statement.continue_label());
1100 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); 1104 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1));
1101 1105
1102 EmitBackEdgeBookkeeping(stmt, &loop); 1106 EmitBackEdgeBookkeeping(stmt, &loop);
1103 __ jmp(&loop); 1107 __ jmp(&loop);
1104 1108
1105 // Remove the pointers stored on the stack. 1109 // Remove the pointers stored on the stack.
1106 __ bind(loop_statement.break_label()); 1110 __ bind(loop_statement.break_label());
1107 DropOperands(5); 1111 DropOperands(5);
1108 1112
1109 // Exit and decrement the loop depth. 1113 // Exit and decrement the loop depth.
1110 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1114 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
1111 __ bind(&exit); 1115 __ bind(&exit);
1112 decrement_loop_depth(); 1116 decrement_loop_depth();
1113 } 1117 }
1114 1118
1115 1119
1116 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1120 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1117 FeedbackVectorSlot slot) { 1121 FeedbackVectorSlot slot) {
1118 DCHECK(NeedsHomeObject(initializer)); 1122 DCHECK(NeedsHomeObject(initializer));
1119 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); 1123 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
1120 __ Move(StoreDescriptor::NameRegister(), 1124 __ Move(StoreDescriptor::NameRegister(),
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 __ Move(LoadDescriptor::SlotRegister(), 1263 __ Move(LoadDescriptor::SlotRegister(),
1260 SmiFromSlot(proxy->VariableFeedbackSlot())); 1264 SmiFromSlot(proxy->VariableFeedbackSlot()));
1261 CallLoadIC(typeof_mode); 1265 CallLoadIC(typeof_mode);
1262 } 1266 }
1263 1267
1264 1268
1265 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1269 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1266 TypeofMode typeof_mode) { 1270 TypeofMode typeof_mode) {
1267 // Record position before possible IC call. 1271 // Record position before possible IC call.
1268 SetExpressionPosition(proxy); 1272 SetExpressionPosition(proxy);
1269 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1273 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1270 Variable* var = proxy->var(); 1274 Variable* var = proxy->var();
1271 1275
1272 // Three cases: global variables, lookup variables, and all other types of 1276 // Three cases: global variables, lookup variables, and all other types of
1273 // variables. 1277 // variables.
1274 switch (var->location()) { 1278 switch (var->location()) {
1275 case VariableLocation::GLOBAL: 1279 case VariableLocation::GLOBAL:
1276 case VariableLocation::UNALLOCATED: { 1280 case VariableLocation::UNALLOCATED: {
1277 Comment cmnt(masm_, "[ Global variable"); 1281 Comment cmnt(masm_, "[ Global variable");
1278 EmitGlobalVariableLoad(proxy, typeof_mode); 1282 EmitGlobalVariableLoad(proxy, typeof_mode);
1279 context()->Plug(rax); 1283 context()->Plug(rax);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 __ CallRuntime(Runtime::kCreateObjectLiteral); 1373 __ CallRuntime(Runtime::kCreateObjectLiteral);
1370 } else { 1374 } else {
1371 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1375 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1372 __ Move(rbx, Smi::FromInt(expr->literal_index())); 1376 __ Move(rbx, Smi::FromInt(expr->literal_index()));
1373 __ Move(rcx, constant_properties); 1377 __ Move(rcx, constant_properties);
1374 __ Move(rdx, Smi::FromInt(flags)); 1378 __ Move(rdx, Smi::FromInt(flags));
1375 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1379 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1376 __ CallStub(&stub); 1380 __ CallStub(&stub);
1377 RestoreContext(); 1381 RestoreContext();
1378 } 1382 }
1379 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1383 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
1380 1384
1381 // If result_saved is true the result is on top of the stack. If 1385 // If result_saved is true the result is on top of the stack. If
1382 // result_saved is false the result is in rax. 1386 // result_saved is false the result is in rax.
1383 bool result_saved = false; 1387 bool result_saved = false;
1384 1388
1385 AccessorTable accessor_table(zone()); 1389 AccessorTable accessor_table(zone());
1386 int property_index = 0; 1390 int property_index = 0;
1387 for (; property_index < expr->properties()->length(); property_index++) { 1391 for (; property_index < expr->properties()->length(); property_index++) {
1388 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1392 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1389 if (property->is_computed_name()) break; 1393 if (property->is_computed_name()) break;
(...skipping 15 matching lines...) Expand all
1405 // It is safe to use [[Put]] here because the boilerplate already 1409 // It is safe to use [[Put]] here because the boilerplate already
1406 // contains computed properties with an uninitialized value. 1410 // contains computed properties with an uninitialized value.
1407 if (key->value()->IsInternalizedString()) { 1411 if (key->value()->IsInternalizedString()) {
1408 if (property->emit_store()) { 1412 if (property->emit_store()) {
1409 VisitForAccumulatorValue(value); 1413 VisitForAccumulatorValue(value);
1410 DCHECK(StoreDescriptor::ValueRegister().is(rax)); 1414 DCHECK(StoreDescriptor::ValueRegister().is(rax));
1411 __ Move(StoreDescriptor::NameRegister(), key->value()); 1415 __ Move(StoreDescriptor::NameRegister(), key->value());
1412 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); 1416 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
1413 EmitLoadStoreICSlot(property->GetSlot(0)); 1417 EmitLoadStoreICSlot(property->GetSlot(0));
1414 CallStoreIC(); 1418 CallStoreIC();
1415 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1419 PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS);
1416 1420
1417 if (NeedsHomeObject(value)) { 1421 if (NeedsHomeObject(value)) {
1418 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1422 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1419 } 1423 }
1420 } else { 1424 } else {
1421 VisitForEffect(value); 1425 VisitForEffect(value);
1422 } 1426 }
1423 break; 1427 break;
1424 } 1428 }
1425 PushOperand(Operand(rsp, 0)); // Duplicate receiver. 1429 PushOperand(Operand(rsp, 0)); // Duplicate receiver.
1426 VisitForStackValue(key); 1430 VisitForStackValue(key);
1427 VisitForStackValue(value); 1431 VisitForStackValue(value);
1428 if (property->emit_store()) { 1432 if (property->emit_store()) {
1429 if (NeedsHomeObject(value)) { 1433 if (NeedsHomeObject(value)) {
1430 EmitSetHomeObject(value, 2, property->GetSlot()); 1434 EmitSetHomeObject(value, 2, property->GetSlot());
1431 } 1435 }
1432 PushOperand(Smi::FromInt(SLOPPY)); // Language mode 1436 PushOperand(Smi::FromInt(SLOPPY)); // Language mode
1433 CallRuntimeWithOperands(Runtime::kSetProperty); 1437 CallRuntimeWithOperands(Runtime::kSetProperty);
1434 } else { 1438 } else {
1435 DropOperands(3); 1439 DropOperands(3);
1436 } 1440 }
1437 break; 1441 break;
1438 case ObjectLiteral::Property::PROTOTYPE: 1442 case ObjectLiteral::Property::PROTOTYPE:
1439 PushOperand(Operand(rsp, 0)); // Duplicate receiver. 1443 PushOperand(Operand(rsp, 0)); // Duplicate receiver.
1440 VisitForStackValue(value); 1444 VisitForStackValue(value);
1441 DCHECK(property->emit_store()); 1445 DCHECK(property->emit_store());
1442 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1446 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1443 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1447 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1444 NO_REGISTERS); 1448 BailoutState::NO_REGISTERS);
1445 break; 1449 break;
1446 case ObjectLiteral::Property::GETTER: 1450 case ObjectLiteral::Property::GETTER:
1447 if (property->emit_store()) { 1451 if (property->emit_store()) {
1448 accessor_table.lookup(key)->second->getter = property; 1452 accessor_table.lookup(key)->second->getter = property;
1449 } 1453 }
1450 break; 1454 break;
1451 case ObjectLiteral::Property::SETTER: 1455 case ObjectLiteral::Property::SETTER:
1452 if (property->emit_store()) { 1456 if (property->emit_store()) {
1453 accessor_table.lookup(key)->second->setter = property; 1457 accessor_table.lookup(key)->second->setter = property;
1454 } 1458 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 } 1492 }
1489 1493
1490 PushOperand(Operand(rsp, 0)); // Duplicate receiver. 1494 PushOperand(Operand(rsp, 0)); // Duplicate receiver.
1491 1495
1492 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1496 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1493 DCHECK(!property->is_computed_name()); 1497 DCHECK(!property->is_computed_name());
1494 VisitForStackValue(value); 1498 VisitForStackValue(value);
1495 DCHECK(property->emit_store()); 1499 DCHECK(property->emit_store());
1496 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1500 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1497 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1501 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1498 NO_REGISTERS); 1502 BailoutState::NO_REGISTERS);
1499 } else { 1503 } else {
1500 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1504 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1501 VisitForStackValue(value); 1505 VisitForStackValue(value);
1502 if (NeedsHomeObject(value)) { 1506 if (NeedsHomeObject(value)) {
1503 EmitSetHomeObject(value, 2, property->GetSlot()); 1507 EmitSetHomeObject(value, 2, property->GetSlot());
1504 } 1508 }
1505 1509
1506 switch (property->kind()) { 1510 switch (property->kind()) {
1507 case ObjectLiteral::Property::CONSTANT: 1511 case ObjectLiteral::Property::CONSTANT:
1508 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1512 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 __ Push(constant_elements); 1565 __ Push(constant_elements);
1562 __ Push(Smi::FromInt(expr->ComputeFlags())); 1566 __ Push(Smi::FromInt(expr->ComputeFlags()));
1563 __ CallRuntime(Runtime::kCreateArrayLiteral); 1567 __ CallRuntime(Runtime::kCreateArrayLiteral);
1564 } else { 1568 } else {
1565 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1569 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1566 __ Move(rbx, Smi::FromInt(expr->literal_index())); 1570 __ Move(rbx, Smi::FromInt(expr->literal_index()));
1567 __ Move(rcx, constant_elements); 1571 __ Move(rcx, constant_elements);
1568 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1572 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1569 __ CallStub(&stub); 1573 __ CallStub(&stub);
1570 } 1574 }
1571 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1575 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
1572 1576
1573 bool result_saved = false; // Is the result saved to the stack? 1577 bool result_saved = false; // Is the result saved to the stack?
1574 ZoneList<Expression*>* subexprs = expr->values(); 1578 ZoneList<Expression*>* subexprs = expr->values();
1575 int length = subexprs->length(); 1579 int length = subexprs->length();
1576 1580
1577 // Emit code to evaluate all the non-constant subexpressions and to store 1581 // Emit code to evaluate all the non-constant subexpressions and to store
1578 // them into the newly cloned array. 1582 // them into the newly cloned array.
1579 int array_index = 0; 1583 int array_index = 0;
1580 for (; array_index < length; array_index++) { 1584 for (; array_index < length; array_index++) {
1581 Expression* subexpr = subexprs->at(array_index); 1585 Expression* subexpr = subexprs->at(array_index);
1582 DCHECK(!subexpr->IsSpread()); 1586 DCHECK(!subexpr->IsSpread());
1583 1587
1584 // If the subexpression is a literal or a simple materialized literal it 1588 // If the subexpression is a literal or a simple materialized literal it
1585 // is already set in the cloned array. 1589 // is already set in the cloned array.
1586 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1590 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1587 1591
1588 if (!result_saved) { 1592 if (!result_saved) {
1589 PushOperand(rax); // array literal 1593 PushOperand(rax); // array literal
1590 result_saved = true; 1594 result_saved = true;
1591 } 1595 }
1592 VisitForAccumulatorValue(subexpr); 1596 VisitForAccumulatorValue(subexpr);
1593 1597
1594 __ Move(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); 1598 __ Move(StoreDescriptor::NameRegister(), Smi::FromInt(array_index));
1595 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); 1599 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
1596 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1600 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1597 Handle<Code> ic = 1601 Handle<Code> ic =
1598 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1602 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1599 CallIC(ic); 1603 CallIC(ic);
1600 1604
1601 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1605 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1606 BailoutState::NO_REGISTERS);
1602 } 1607 }
1603 1608
1604 // In case the array literal contains spread expressions it has two parts. The 1609 // In case the array literal contains spread expressions it has two parts. The
1605 // first part is the "static" array which has a literal index is handled 1610 // first part is the "static" array which has a literal index is handled
1606 // above. The second part is the part after the first spread expression 1611 // above. The second part is the part after the first spread expression
1607 // (inclusive) and these elements gets appended to the array. Note that the 1612 // (inclusive) and these elements gets appended to the array. Note that the
1608 // number elements an iterable produces is unknown ahead of time. 1613 // number elements an iterable produces is unknown ahead of time.
1609 if (array_index < length && result_saved) { 1614 if (array_index < length && result_saved) {
1610 PopOperand(rax); 1615 PopOperand(rax);
1611 result_saved = false; 1616 result_saved = false;
1612 } 1617 }
1613 for (; array_index < length; array_index++) { 1618 for (; array_index < length; array_index++) {
1614 Expression* subexpr = subexprs->at(array_index); 1619 Expression* subexpr = subexprs->at(array_index);
1615 1620
1616 PushOperand(rax); 1621 PushOperand(rax);
1617 DCHECK(!subexpr->IsSpread()); 1622 DCHECK(!subexpr->IsSpread());
1618 VisitForStackValue(subexpr); 1623 VisitForStackValue(subexpr);
1619 CallRuntimeWithOperands(Runtime::kAppendElement); 1624 CallRuntimeWithOperands(Runtime::kAppendElement);
1620 1625
1621 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1626 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1627 BailoutState::NO_REGISTERS);
1622 } 1628 }
1623 1629
1624 if (result_saved) { 1630 if (result_saved) {
1625 context()->PlugTOS(); 1631 context()->PlugTOS();
1626 } else { 1632 } else {
1627 context()->Plug(rax); 1633 context()->Plug(rax);
1628 } 1634 }
1629 } 1635 }
1630 1636
1631 1637
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 } 1695 }
1690 } 1696 }
1691 1697
1692 // For compound assignments we need another deoptimization point after the 1698 // For compound assignments we need another deoptimization point after the
1693 // variable/property load. 1699 // variable/property load.
1694 if (expr->is_compound()) { 1700 if (expr->is_compound()) {
1695 { AccumulatorValueContext context(this); 1701 { AccumulatorValueContext context(this);
1696 switch (assign_type) { 1702 switch (assign_type) {
1697 case VARIABLE: 1703 case VARIABLE:
1698 EmitVariableLoad(expr->target()->AsVariableProxy()); 1704 EmitVariableLoad(expr->target()->AsVariableProxy());
1699 PrepareForBailout(expr->target(), TOS_REG); 1705 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER);
1700 break; 1706 break;
1701 case NAMED_PROPERTY: 1707 case NAMED_PROPERTY:
1702 EmitNamedPropertyLoad(property); 1708 EmitNamedPropertyLoad(property);
1703 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1709 PrepareForBailoutForId(property->LoadId(),
1710 BailoutState::TOS_REGISTER);
1704 break; 1711 break;
1705 case NAMED_SUPER_PROPERTY: 1712 case NAMED_SUPER_PROPERTY:
1706 EmitNamedSuperPropertyLoad(property); 1713 EmitNamedSuperPropertyLoad(property);
1707 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1714 PrepareForBailoutForId(property->LoadId(),
1715 BailoutState::TOS_REGISTER);
1708 break; 1716 break;
1709 case KEYED_SUPER_PROPERTY: 1717 case KEYED_SUPER_PROPERTY:
1710 EmitKeyedSuperPropertyLoad(property); 1718 EmitKeyedSuperPropertyLoad(property);
1711 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1719 PrepareForBailoutForId(property->LoadId(),
1720 BailoutState::TOS_REGISTER);
1712 break; 1721 break;
1713 case KEYED_PROPERTY: 1722 case KEYED_PROPERTY:
1714 EmitKeyedPropertyLoad(property); 1723 EmitKeyedPropertyLoad(property);
1715 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1724 PrepareForBailoutForId(property->LoadId(),
1725 BailoutState::TOS_REGISTER);
1716 break; 1726 break;
1717 } 1727 }
1718 } 1728 }
1719 1729
1720 Token::Value op = expr->binary_op(); 1730 Token::Value op = expr->binary_op();
1721 PushOperand(rax); // Left operand goes on the stack. 1731 PushOperand(rax); // Left operand goes on the stack.
1722 VisitForAccumulatorValue(expr->value()); 1732 VisitForAccumulatorValue(expr->value());
1723 1733
1724 AccumulatorValueContext context(this); 1734 AccumulatorValueContext context(this);
1725 if (ShouldInlineSmiCase(op)) { 1735 if (ShouldInlineSmiCase(op)) {
1726 EmitInlineSmiBinaryOp(expr->binary_operation(), 1736 EmitInlineSmiBinaryOp(expr->binary_operation(),
1727 op, 1737 op,
1728 expr->target(), 1738 expr->target(),
1729 expr->value()); 1739 expr->value());
1730 } else { 1740 } else {
1731 EmitBinaryOp(expr->binary_operation(), op); 1741 EmitBinaryOp(expr->binary_operation(), op);
1732 } 1742 }
1733 // Deoptimization point in case the binary operation may have side effects. 1743 // Deoptimization point in case the binary operation may have side effects.
1734 PrepareForBailout(expr->binary_operation(), TOS_REG); 1744 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER);
1735 } else { 1745 } else {
1736 VisitForAccumulatorValue(expr->value()); 1746 VisitForAccumulatorValue(expr->value());
1737 } 1747 }
1738 1748
1739 SetExpressionPosition(expr); 1749 SetExpressionPosition(expr);
1740 1750
1741 // Store the value. 1751 // Store the value.
1742 switch (assign_type) { 1752 switch (assign_type) {
1743 case VARIABLE: 1753 case VARIABLE:
1744 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1754 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1745 expr->op(), expr->AssignmentSlot()); 1755 expr->op(), expr->AssignmentSlot());
1746 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1756 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1747 context()->Plug(rax); 1757 context()->Plug(rax);
1748 break; 1758 break;
1749 case NAMED_PROPERTY: 1759 case NAMED_PROPERTY:
1750 EmitNamedPropertyAssignment(expr); 1760 EmitNamedPropertyAssignment(expr);
1751 break; 1761 break;
1752 case NAMED_SUPER_PROPERTY: 1762 case NAMED_SUPER_PROPERTY:
1753 EmitNamedSuperPropertyStore(property); 1763 EmitNamedSuperPropertyStore(property);
1754 context()->Plug(rax); 1764 context()->Plug(rax);
1755 break; 1765 break;
1756 case KEYED_SUPER_PROPERTY: 1766 case KEYED_SUPER_PROPERTY:
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 // Assignment to a property, using a named store IC. 2169 // Assignment to a property, using a named store IC.
2160 Property* prop = expr->target()->AsProperty(); 2170 Property* prop = expr->target()->AsProperty();
2161 DCHECK(prop != NULL); 2171 DCHECK(prop != NULL);
2162 DCHECK(prop->key()->IsLiteral()); 2172 DCHECK(prop->key()->IsLiteral());
2163 2173
2164 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); 2174 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2165 PopOperand(StoreDescriptor::ReceiverRegister()); 2175 PopOperand(StoreDescriptor::ReceiverRegister());
2166 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2176 EmitLoadStoreICSlot(expr->AssignmentSlot());
2167 CallStoreIC(); 2177 CallStoreIC();
2168 2178
2169 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2179 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2170 context()->Plug(rax); 2180 context()->Plug(rax);
2171 } 2181 }
2172 2182
2173 2183
2174 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2184 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2175 // Assignment to named property of super. 2185 // Assignment to named property of super.
2176 // rax : value 2186 // rax : value
2177 // stack : receiver ('this'), home_object 2187 // stack : receiver ('this'), home_object
2178 DCHECK(prop != NULL); 2188 DCHECK(prop != NULL);
2179 Literal* key = prop->key()->AsLiteral(); 2189 Literal* key = prop->key()->AsLiteral();
(...skipping 23 matching lines...) Expand all
2203 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2213 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2204 // Assignment to a property, using a keyed store IC. 2214 // Assignment to a property, using a keyed store IC.
2205 PopOperand(StoreDescriptor::NameRegister()); // Key. 2215 PopOperand(StoreDescriptor::NameRegister()); // Key.
2206 PopOperand(StoreDescriptor::ReceiverRegister()); 2216 PopOperand(StoreDescriptor::ReceiverRegister());
2207 DCHECK(StoreDescriptor::ValueRegister().is(rax)); 2217 DCHECK(StoreDescriptor::ValueRegister().is(rax));
2208 Handle<Code> ic = 2218 Handle<Code> ic =
2209 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2219 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2210 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2220 EmitLoadStoreICSlot(expr->AssignmentSlot());
2211 CallIC(ic); 2221 CallIC(ic);
2212 2222
2213 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2223 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2214 context()->Plug(rax); 2224 context()->Plug(rax);
2215 } 2225 }
2216 2226
2217 2227
2218 void FullCodeGenerator::CallIC(Handle<Code> code, 2228 void FullCodeGenerator::CallIC(Handle<Code> code,
2219 TypeFeedbackId ast_id) { 2229 TypeFeedbackId ast_id) {
2220 ic_total_count_++; 2230 ic_total_count_++;
2221 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2231 __ call(code, RelocInfo::CODE_TARGET, ast_id);
2222 } 2232 }
2223 2233
2224 2234
2225 // Code common for calls using the IC. 2235 // Code common for calls using the IC.
2226 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2236 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2227 Expression* callee = expr->expression(); 2237 Expression* callee = expr->expression();
2228 2238
2229 // Get the target function. 2239 // Get the target function.
2230 ConvertReceiverMode convert_mode; 2240 ConvertReceiverMode convert_mode;
2231 if (callee->IsVariableProxy()) { 2241 if (callee->IsVariableProxy()) {
2232 { StackValueContext context(this); 2242 { StackValueContext context(this);
2233 EmitVariableLoad(callee->AsVariableProxy()); 2243 EmitVariableLoad(callee->AsVariableProxy());
2234 PrepareForBailout(callee, NO_REGISTERS); 2244 PrepareForBailout(callee, BailoutState::NO_REGISTERS);
2235 } 2245 }
2236 // Push undefined as receiver. This is patched in the Call builtin if it 2246 // Push undefined as receiver. This is patched in the Call builtin if it
2237 // is a sloppy mode method. 2247 // is a sloppy mode method.
2238 PushOperand(isolate()->factory()->undefined_value()); 2248 PushOperand(isolate()->factory()->undefined_value());
2239 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2249 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2240 } else { 2250 } else {
2241 // Load the function from the receiver. 2251 // Load the function from the receiver.
2242 DCHECK(callee->IsProperty()); 2252 DCHECK(callee->IsProperty());
2243 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2253 DCHECK(!callee->AsProperty()->IsSuperAccess());
2244 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); 2254 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
2245 EmitNamedPropertyLoad(callee->AsProperty()); 2255 EmitNamedPropertyLoad(callee->AsProperty());
2246 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2256 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2257 BailoutState::TOS_REGISTER);
2247 // Push the target function under the receiver. 2258 // Push the target function under the receiver.
2248 PushOperand(Operand(rsp, 0)); 2259 PushOperand(Operand(rsp, 0));
2249 __ movp(Operand(rsp, kPointerSize), rax); 2260 __ movp(Operand(rsp, kPointerSize), rax);
2250 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2261 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2251 } 2262 }
2252 2263
2253 EmitCall(expr, convert_mode); 2264 EmitCall(expr, convert_mode);
2254 } 2265 }
2255 2266
2256 2267
(...skipping 15 matching lines...) Expand all
2272 PushOperand(Operand(rsp, kPointerSize * 2)); 2283 PushOperand(Operand(rsp, kPointerSize * 2));
2273 PushOperand(key->value()); 2284 PushOperand(key->value());
2274 2285
2275 // Stack here: 2286 // Stack here:
2276 // - home_object 2287 // - home_object
2277 // - this (receiver) 2288 // - this (receiver)
2278 // - this (receiver) <-- LoadFromSuper will pop here and below. 2289 // - this (receiver) <-- LoadFromSuper will pop here and below.
2279 // - home_object 2290 // - home_object
2280 // - key 2291 // - key
2281 CallRuntimeWithOperands(Runtime::kLoadFromSuper); 2292 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2282 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2293 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2283 2294
2284 // Replace home_object with target function. 2295 // Replace home_object with target function.
2285 __ movp(Operand(rsp, kPointerSize), rax); 2296 __ movp(Operand(rsp, kPointerSize), rax);
2286 2297
2287 // Stack here: 2298 // Stack here:
2288 // - target function 2299 // - target function
2289 // - this (receiver) 2300 // - this (receiver)
2290 EmitCall(expr); 2301 EmitCall(expr);
2291 } 2302 }
2292 2303
2293 2304
2294 // Common code for calls using the IC. 2305 // Common code for calls using the IC.
2295 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2306 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2296 Expression* key) { 2307 Expression* key) {
2297 // Load the key. 2308 // Load the key.
2298 VisitForAccumulatorValue(key); 2309 VisitForAccumulatorValue(key);
2299 2310
2300 Expression* callee = expr->expression(); 2311 Expression* callee = expr->expression();
2301 2312
2302 // Load the function from the receiver. 2313 // Load the function from the receiver.
2303 DCHECK(callee->IsProperty()); 2314 DCHECK(callee->IsProperty());
2304 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); 2315 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
2305 __ Move(LoadDescriptor::NameRegister(), rax); 2316 __ Move(LoadDescriptor::NameRegister(), rax);
2306 EmitKeyedPropertyLoad(callee->AsProperty()); 2317 EmitKeyedPropertyLoad(callee->AsProperty());
2307 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2318 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2319 BailoutState::TOS_REGISTER);
2308 2320
2309 // Push the target function under the receiver. 2321 // Push the target function under the receiver.
2310 PushOperand(Operand(rsp, 0)); 2322 PushOperand(Operand(rsp, 0));
2311 __ movp(Operand(rsp, kPointerSize), rax); 2323 __ movp(Operand(rsp, kPointerSize), rax);
2312 2324
2313 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2325 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2314 } 2326 }
2315 2327
2316 2328
2317 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2329 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
(...skipping 12 matching lines...) Expand all
2330 PushOperand(Operand(rsp, kPointerSize * 2)); 2342 PushOperand(Operand(rsp, kPointerSize * 2));
2331 VisitForStackValue(prop->key()); 2343 VisitForStackValue(prop->key());
2332 2344
2333 // Stack here: 2345 // Stack here:
2334 // - home_object 2346 // - home_object
2335 // - this (receiver) 2347 // - this (receiver)
2336 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2348 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2337 // - home_object 2349 // - home_object
2338 // - key 2350 // - key
2339 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); 2351 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2340 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2352 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2341 2353
2342 // Replace home_object with target function. 2354 // Replace home_object with target function.
2343 __ movp(Operand(rsp, kPointerSize), rax); 2355 __ movp(Operand(rsp, kPointerSize), rax);
2344 2356
2345 // Stack here: 2357 // Stack here:
2346 // - target function 2358 // - target function
2347 // - this (receiver) 2359 // - this (receiver)
2348 EmitCall(expr); 2360 EmitCall(expr);
2349 } 2361 }
2350 2362
2351 2363
2352 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { 2364 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
2353 // Load the arguments. 2365 // Load the arguments.
2354 ZoneList<Expression*>* args = expr->arguments(); 2366 ZoneList<Expression*>* args = expr->arguments();
2355 int arg_count = args->length(); 2367 int arg_count = args->length();
2356 for (int i = 0; i < arg_count; i++) { 2368 for (int i = 0; i < arg_count; i++) {
2357 VisitForStackValue(args->at(i)); 2369 VisitForStackValue(args->at(i));
2358 } 2370 }
2359 2371
2360 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2372 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
2361 SetCallPosition(expr, expr->tail_call_mode()); 2373 SetCallPosition(expr, expr->tail_call_mode());
2362 if (expr->tail_call_mode() == TailCallMode::kAllow) { 2374 if (expr->tail_call_mode() == TailCallMode::kAllow) {
2363 if (FLAG_trace) { 2375 if (FLAG_trace) {
2364 __ CallRuntime(Runtime::kTraceTailCall); 2376 __ CallRuntime(Runtime::kTraceTailCall);
2365 } 2377 }
2366 // Update profiling counters before the tail call since we will 2378 // Update profiling counters before the tail call since we will
2367 // not return to this function. 2379 // not return to this function.
2368 EmitProfilingCounterHandlingForReturnSequence(true); 2380 EmitProfilingCounterHandlingForReturnSequence(true);
2369 } 2381 }
2370 Handle<Code> ic = 2382 Handle<Code> ic =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2418 // Generate code for loading from variables potentially shadowed by 2430 // Generate code for loading from variables potentially shadowed by
2419 // eval-introduced variables. 2431 // eval-introduced variables.
2420 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2432 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2421 __ bind(&slow); 2433 __ bind(&slow);
2422 // Call the runtime to find the function to call (returned in rax) and 2434 // Call the runtime to find the function to call (returned in rax) and
2423 // the object holding it (returned in rdx). 2435 // the object holding it (returned in rdx).
2424 __ Push(callee->name()); 2436 __ Push(callee->name());
2425 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2437 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2426 PushOperand(rax); // Function. 2438 PushOperand(rax); // Function.
2427 PushOperand(rdx); // Receiver. 2439 PushOperand(rdx); // Receiver.
2428 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2440 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2429 2441
2430 // If fast case code has been generated, emit code to push the function 2442 // If fast case code has been generated, emit code to push the function
2431 // and receiver and have the slow path jump around this code. 2443 // and receiver and have the slow path jump around this code.
2432 if (done.is_linked()) { 2444 if (done.is_linked()) {
2433 Label call; 2445 Label call;
2434 __ jmp(&call, Label::kNear); 2446 __ jmp(&call, Label::kNear);
2435 __ bind(&done); 2447 __ bind(&done);
2436 // Push function. 2448 // Push function.
2437 __ Push(rax); 2449 __ Push(rax);
2438 // Pass undefined as the receiver, which is the WithBaseObject of a 2450 // Pass undefined as the receiver, which is the WithBaseObject of a
(...skipping 25 matching lines...) Expand all
2464 } 2476 }
2465 2477
2466 // Push a copy of the function (found below the arguments) and resolve 2478 // Push a copy of the function (found below the arguments) and resolve
2467 // eval. 2479 // eval.
2468 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); 2480 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize));
2469 EmitResolvePossiblyDirectEval(expr); 2481 EmitResolvePossiblyDirectEval(expr);
2470 2482
2471 // Touch up the callee. 2483 // Touch up the callee.
2472 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); 2484 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
2473 2485
2474 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2486 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2475 2487
2476 SetCallPosition(expr); 2488 SetCallPosition(expr);
2477 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 2489 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
2478 __ Set(rax, arg_count); 2490 __ Set(rax, arg_count);
2479 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2491 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2480 expr->tail_call_mode()), 2492 expr->tail_call_mode()),
2481 RelocInfo::CODE_TARGET); 2493 RelocInfo::CODE_TARGET);
2482 OperandStackDepthDecrement(arg_count + 1); 2494 OperandStackDepthDecrement(arg_count + 1);
2483 RecordJSReturnSite(expr); 2495 RecordJSReturnSite(expr);
2484 RestoreContext(); 2496 RestoreContext();
(...skipping 28 matching lines...) Expand all
2513 __ Set(rax, arg_count); 2525 __ Set(rax, arg_count);
2514 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); 2526 __ movp(rdi, Operand(rsp, arg_count * kPointerSize));
2515 2527
2516 // Record call targets in unoptimized code, but not in the snapshot. 2528 // Record call targets in unoptimized code, but not in the snapshot.
2517 __ EmitLoadTypeFeedbackVector(rbx); 2529 __ EmitLoadTypeFeedbackVector(rbx);
2518 __ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot())); 2530 __ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot()));
2519 2531
2520 CallConstructStub stub(isolate()); 2532 CallConstructStub stub(isolate());
2521 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2533 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2522 OperandStackDepthDecrement(arg_count + 1); 2534 OperandStackDepthDecrement(arg_count + 1);
2523 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2535 PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER);
2524 RestoreContext(); 2536 RestoreContext();
2525 context()->Plug(rax); 2537 context()->Plug(rax);
2526 } 2538 }
2527 2539
2528 2540
2529 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2541 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2530 SuperCallReference* super_call_ref = 2542 SuperCallReference* super_call_ref =
2531 expr->expression()->AsSuperCallReference(); 2543 expr->expression()->AsSuperCallReference();
2532 DCHECK_NOT_NULL(super_call_ref); 2544 DCHECK_NOT_NULL(super_call_ref);
2533 2545
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
2946 } 2958 }
2947 2959
2948 2960
2949 void FullCodeGenerator::EmitCall(CallRuntime* expr) { 2961 void FullCodeGenerator::EmitCall(CallRuntime* expr) {
2950 ZoneList<Expression*>* args = expr->arguments(); 2962 ZoneList<Expression*>* args = expr->arguments();
2951 DCHECK_LE(2, args->length()); 2963 DCHECK_LE(2, args->length());
2952 // Push target, receiver and arguments onto the stack. 2964 // Push target, receiver and arguments onto the stack.
2953 for (Expression* const arg : *args) { 2965 for (Expression* const arg : *args) {
2954 VisitForStackValue(arg); 2966 VisitForStackValue(arg);
2955 } 2967 }
2956 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2968 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
2957 // Move target to rdi. 2969 // Move target to rdi.
2958 int const argc = args->length() - 2; 2970 int const argc = args->length() - 2;
2959 __ movp(rdi, Operand(rsp, (argc + 1) * kPointerSize)); 2971 __ movp(rdi, Operand(rsp, (argc + 1) * kPointerSize));
2960 // Call the target. 2972 // Call the target.
2961 __ Set(rax, argc); 2973 __ Set(rax, argc);
2962 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 2974 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2963 OperandStackDepthDecrement(argc + 1); 2975 OperandStackDepthDecrement(argc + 1);
2964 RestoreContext(); 2976 RestoreContext();
2965 // Discard the function left on TOS. 2977 // Discard the function left on TOS.
2966 context()->DropAndPlug(1, rax); 2978 context()->DropAndPlug(1, rax);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
3159 // because we need to prepare a pair of extra administrative AST ids 3171 // because we need to prepare a pair of extra administrative AST ids
3160 // for the optimizing compiler. 3172 // for the optimizing compiler.
3161 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3173 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3162 Label materialize_true, materialize_false, done; 3174 Label materialize_true, materialize_false, done;
3163 VisitForControl(expr->expression(), 3175 VisitForControl(expr->expression(),
3164 &materialize_false, 3176 &materialize_false,
3165 &materialize_true, 3177 &materialize_true,
3166 &materialize_true); 3178 &materialize_true);
3167 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); 3179 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3168 __ bind(&materialize_true); 3180 __ bind(&materialize_true);
3169 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3181 PrepareForBailoutForId(expr->MaterializeTrueId(),
3182 BailoutState::NO_REGISTERS);
3170 if (context()->IsAccumulatorValue()) { 3183 if (context()->IsAccumulatorValue()) {
3171 __ LoadRoot(rax, Heap::kTrueValueRootIndex); 3184 __ LoadRoot(rax, Heap::kTrueValueRootIndex);
3172 } else { 3185 } else {
3173 __ PushRoot(Heap::kTrueValueRootIndex); 3186 __ PushRoot(Heap::kTrueValueRootIndex);
3174 } 3187 }
3175 __ jmp(&done, Label::kNear); 3188 __ jmp(&done, Label::kNear);
3176 __ bind(&materialize_false); 3189 __ bind(&materialize_false);
3177 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3190 PrepareForBailoutForId(expr->MaterializeFalseId(),
3191 BailoutState::NO_REGISTERS);
3178 if (context()->IsAccumulatorValue()) { 3192 if (context()->IsAccumulatorValue()) {
3179 __ LoadRoot(rax, Heap::kFalseValueRootIndex); 3193 __ LoadRoot(rax, Heap::kFalseValueRootIndex);
3180 } else { 3194 } else {
3181 __ PushRoot(Heap::kFalseValueRootIndex); 3195 __ PushRoot(Heap::kFalseValueRootIndex);
3182 } 3196 }
3183 __ bind(&done); 3197 __ bind(&done);
3184 } 3198 }
3185 break; 3199 break;
3186 } 3200 }
3187 3201
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 } 3280 }
3267 3281
3268 case VARIABLE: 3282 case VARIABLE:
3269 UNREACHABLE(); 3283 UNREACHABLE();
3270 } 3284 }
3271 } 3285 }
3272 3286
3273 // We need a second deoptimization point after loading the value 3287 // We need a second deoptimization point after loading the value
3274 // in case evaluating the property load my have a side effect. 3288 // in case evaluating the property load my have a side effect.
3275 if (assign_type == VARIABLE) { 3289 if (assign_type == VARIABLE) {
3276 PrepareForBailout(expr->expression(), TOS_REG); 3290 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER);
3277 } else { 3291 } else {
3278 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 3292 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
3279 } 3293 }
3280 3294
3281 // Inline smi case if we are in a loop. 3295 // Inline smi case if we are in a loop.
3282 Label done, stub_call; 3296 Label done, stub_call;
3283 JumpPatchSite patch_site(masm_); 3297 JumpPatchSite patch_site(masm_);
3284 if (ShouldInlineSmiCase(expr->op())) { 3298 if (ShouldInlineSmiCase(expr->op())) {
3285 Label slow; 3299 Label slow;
3286 patch_site.EmitJumpIfNotSmi(rax, &slow, Label::kNear); 3300 patch_site.EmitJumpIfNotSmi(rax, &slow, Label::kNear);
3287 3301
3288 // Save result for postfix expressions. 3302 // Save result for postfix expressions.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3321 __ SmiSubConstant(rax, rax, Smi::FromInt(1), constraints, &done, 3335 __ SmiSubConstant(rax, rax, Smi::FromInt(1), constraints, &done,
3322 Label::kNear); 3336 Label::kNear);
3323 } 3337 }
3324 __ jmp(&stub_call, Label::kNear); 3338 __ jmp(&stub_call, Label::kNear);
3325 __ bind(&slow); 3339 __ bind(&slow);
3326 } 3340 }
3327 3341
3328 // Convert old value into a number. 3342 // Convert old value into a number.
3329 ToNumberStub convert_stub(isolate()); 3343 ToNumberStub convert_stub(isolate());
3330 __ CallStub(&convert_stub); 3344 __ CallStub(&convert_stub);
3331 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); 3345 PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
3332 3346
3333 // Save result for postfix expressions. 3347 // Save result for postfix expressions.
3334 if (expr->is_postfix()) { 3348 if (expr->is_postfix()) {
3335 if (!context()->IsEffect()) { 3349 if (!context()->IsEffect()) {
3336 // Save the result on the stack. If we have a named or keyed property 3350 // Save the result on the stack. If we have a named or keyed property
3337 // we store the result under the receiver that is currently on top 3351 // we store the result under the receiver that is currently on top
3338 // of the stack. 3352 // of the stack.
3339 switch (assign_type) { 3353 switch (assign_type) {
3340 case VARIABLE: 3354 case VARIABLE:
3341 PushOperand(rax); 3355 PushOperand(rax);
(...skipping 27 matching lines...) Expand all
3369 __ bind(&done); 3383 __ bind(&done);
3370 3384
3371 // Store the value returned in rax. 3385 // Store the value returned in rax.
3372 switch (assign_type) { 3386 switch (assign_type) {
3373 case VARIABLE: 3387 case VARIABLE:
3374 if (expr->is_postfix()) { 3388 if (expr->is_postfix()) {
3375 // Perform the assignment as if via '='. 3389 // Perform the assignment as if via '='.
3376 { EffectContext context(this); 3390 { EffectContext context(this);
3377 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3391 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3378 Token::ASSIGN, expr->CountSlot()); 3392 Token::ASSIGN, expr->CountSlot());
3379 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3393 PrepareForBailoutForId(expr->AssignmentId(),
3394 BailoutState::TOS_REGISTER);
3380 context.Plug(rax); 3395 context.Plug(rax);
3381 } 3396 }
3382 // For all contexts except kEffect: We have the result on 3397 // For all contexts except kEffect: We have the result on
3383 // top of the stack. 3398 // top of the stack.
3384 if (!context()->IsEffect()) { 3399 if (!context()->IsEffect()) {
3385 context()->PlugTOS(); 3400 context()->PlugTOS();
3386 } 3401 }
3387 } else { 3402 } else {
3388 // Perform the assignment as if via '='. 3403 // Perform the assignment as if via '='.
3389 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3404 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3390 Token::ASSIGN, expr->CountSlot()); 3405 Token::ASSIGN, expr->CountSlot());
3391 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3406 PrepareForBailoutForId(expr->AssignmentId(),
3407 BailoutState::TOS_REGISTER);
3392 context()->Plug(rax); 3408 context()->Plug(rax);
3393 } 3409 }
3394 break; 3410 break;
3395 case NAMED_PROPERTY: { 3411 case NAMED_PROPERTY: {
3396 __ Move(StoreDescriptor::NameRegister(), 3412 __ Move(StoreDescriptor::NameRegister(),
3397 prop->key()->AsLiteral()->value()); 3413 prop->key()->AsLiteral()->value());
3398 PopOperand(StoreDescriptor::ReceiverRegister()); 3414 PopOperand(StoreDescriptor::ReceiverRegister());
3399 EmitLoadStoreICSlot(expr->CountSlot()); 3415 EmitLoadStoreICSlot(expr->CountSlot());
3400 CallStoreIC(); 3416 CallStoreIC();
3401 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3417 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3402 if (expr->is_postfix()) { 3418 if (expr->is_postfix()) {
3403 if (!context()->IsEffect()) { 3419 if (!context()->IsEffect()) {
3404 context()->PlugTOS(); 3420 context()->PlugTOS();
3405 } 3421 }
3406 } else { 3422 } else {
3407 context()->Plug(rax); 3423 context()->Plug(rax);
3408 } 3424 }
3409 break; 3425 break;
3410 } 3426 }
3411 case NAMED_SUPER_PROPERTY: { 3427 case NAMED_SUPER_PROPERTY: {
(...skipping 18 matching lines...) Expand all
3430 } 3446 }
3431 break; 3447 break;
3432 } 3448 }
3433 case KEYED_PROPERTY: { 3449 case KEYED_PROPERTY: {
3434 PopOperand(StoreDescriptor::NameRegister()); 3450 PopOperand(StoreDescriptor::NameRegister());
3435 PopOperand(StoreDescriptor::ReceiverRegister()); 3451 PopOperand(StoreDescriptor::ReceiverRegister());
3436 Handle<Code> ic = 3452 Handle<Code> ic =
3437 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3453 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3438 EmitLoadStoreICSlot(expr->CountSlot()); 3454 EmitLoadStoreICSlot(expr->CountSlot());
3439 CallIC(ic); 3455 CallIC(ic);
3440 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3456 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3441 if (expr->is_postfix()) { 3457 if (expr->is_postfix()) {
3442 if (!context()->IsEffect()) { 3458 if (!context()->IsEffect()) {
3443 context()->PlugTOS(); 3459 context()->PlugTOS();
3444 } 3460 }
3445 } else { 3461 } else {
3446 context()->Plug(rax); 3462 context()->Plug(rax);
3447 } 3463 }
3448 break; 3464 break;
3449 } 3465 }
3450 } 3466 }
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
3811 DCHECK_EQ( 3827 DCHECK_EQ(
3812 isolate->builtins()->OnStackReplacement()->entry(), 3828 isolate->builtins()->OnStackReplacement()->entry(),
3813 Assembler::target_address_at(call_target_address, unoptimized_code)); 3829 Assembler::target_address_at(call_target_address, unoptimized_code));
3814 return ON_STACK_REPLACEMENT; 3830 return ON_STACK_REPLACEMENT;
3815 } 3831 }
3816 3832
3817 } // namespace internal 3833 } // namespace internal
3818 } // namespace v8 3834 } // namespace v8
3819 3835
3820 #endif // V8_TARGET_ARCH_X64 3836 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/full-codegen/mips64/full-codegen-mips64.cc ('k') | src/heap/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698