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

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

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