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

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

Issue 1987053006: X87: [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampol… (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 | « no previous file | src/x87/builtins-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 // Possibly allocate a local context. 161 // Possibly allocate a local context.
162 if (info->scope()->num_heap_slots() > 0) { 162 if (info->scope()->num_heap_slots() > 0) {
163 Comment cmnt(masm_, "[ Allocate context"); 163 Comment cmnt(masm_, "[ Allocate context");
164 bool need_write_barrier = true; 164 bool need_write_barrier = true;
165 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 165 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
166 // Argument to NewContext is the function, which is still in edi. 166 // Argument to NewContext is the function, which is still in edi.
167 if (info->scope()->is_script_scope()) { 167 if (info->scope()->is_script_scope()) {
168 __ push(edi); 168 __ push(edi);
169 __ Push(info->scope()->GetScopeInfo(info->isolate())); 169 __ Push(info->scope()->GetScopeInfo(info->isolate()));
170 __ CallRuntime(Runtime::kNewScriptContext); 170 __ CallRuntime(Runtime::kNewScriptContext);
171 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 171 PrepareForBailoutForId(BailoutId::ScriptContext(),
172 BailoutState::TOS_REGISTER);
172 // The new target value is not used, clobbering is safe. 173 // The new target value is not used, clobbering is safe.
173 DCHECK_NULL(info->scope()->new_target_var()); 174 DCHECK_NULL(info->scope()->new_target_var());
174 } else { 175 } else {
175 if (info->scope()->new_target_var() != nullptr) { 176 if (info->scope()->new_target_var() != nullptr) {
176 __ push(edx); // Preserve new target. 177 __ push(edx); // Preserve new target.
177 } 178 }
178 if (slots <= FastNewContextStub::kMaximumSlots) { 179 if (slots <= FastNewContextStub::kMaximumSlots) {
179 FastNewContextStub stub(isolate(), slots); 180 FastNewContextStub stub(isolate(), slots);
180 __ CallStub(&stub); 181 __ CallStub(&stub);
181 // Result of FastNewContextStub is always in new space. 182 // Result of FastNewContextStub is always in new space.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 __ Abort(kExpectedNewSpaceObject); 218 __ Abort(kExpectedNewSpaceObject);
218 __ bind(&done); 219 __ bind(&done);
219 } 220 }
220 } 221 }
221 } 222 }
222 } 223 }
223 224
224 // Register holding this function and new target are both trashed in case we 225 // Register holding this function and new target are both trashed in case we
225 // bailout here. But since that can happen only when new target is not used 226 // bailout here. But since that can happen only when new target is not used
226 // and we allocate a context, the value of |function_in_register| is correct. 227 // and we allocate a context, the value of |function_in_register| is correct.
227 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); 228 PrepareForBailoutForId(BailoutId::FunctionContext(),
229 BailoutState::NO_REGISTERS);
228 230
229 // Possibly set up a local binding to the this function which is used in 231 // Possibly set up a local binding to the this function which is used in
230 // derived constructors with super calls. 232 // derived constructors with super calls.
231 Variable* this_function_var = scope()->this_function_var(); 233 Variable* this_function_var = scope()->this_function_var();
232 if (this_function_var != nullptr) { 234 if (this_function_var != nullptr) {
233 Comment cmnt(masm_, "[ This function"); 235 Comment cmnt(masm_, "[ This function");
234 if (!function_in_register) { 236 if (!function_in_register) {
235 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 237 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
236 // The write barrier clobbers register again, keep it marked as such. 238 // The write barrier clobbers register again, keep it marked as such.
237 } 239 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 281 }
280 282
281 SetVar(arguments, eax, ebx, edx); 283 SetVar(arguments, eax, ebx, edx);
282 } 284 }
283 285
284 if (FLAG_trace) { 286 if (FLAG_trace) {
285 __ CallRuntime(Runtime::kTraceEnter); 287 __ CallRuntime(Runtime::kTraceEnter);
286 } 288 }
287 289
288 // Visit the declarations and body. 290 // Visit the declarations and body.
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 ExternalReference stack_limit = 308 ExternalReference stack_limit =
305 ExternalReference::address_of_stack_limit(isolate()); 309 ExternalReference::address_of_stack_limit(isolate());
306 __ cmp(esp, Operand::StaticVariable(stack_limit)); 310 __ cmp(esp, Operand::StaticVariable(stack_limit));
307 __ j(above_equal, &ok, Label::kNear); 311 __ j(above_equal, &ok, Label::kNear);
308 __ call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET); 312 __ call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
309 __ bind(&ok); 313 __ bind(&ok);
310 } 314 }
311 315
312 { 316 {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 __ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); 363 __ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
360 364
361 // Record a mapping of this PC offset to the OSR id. This is used to find 365 // Record a mapping of this PC offset to the OSR id. This is used to find
362 // the AST id from the unoptimized code in order to use it as a key into 366 // the AST id from the unoptimized code in order to use it as a key into
363 // the deoptimization input data found in the optimized code. 367 // the deoptimization input data found in the optimized code.
364 RecordBackEdge(stmt->OsrEntryId()); 368 RecordBackEdge(stmt->OsrEntryId());
365 369
366 EmitProfilingCounterReset(); 370 EmitProfilingCounterReset();
367 371
368 __ bind(&ok); 372 __ bind(&ok);
369 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 373 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
370 // Record a mapping of the OSR id to this PC. This is used if the OSR 374 // Record a mapping of the OSR id to this PC. This is used if the OSR
371 // entry becomes the target of a bailout. We don't expect it to be, but 375 // entry becomes the target of a bailout. We don't expect it to be, but
372 // we want it to work if it is. 376 // we want it to work if it is.
373 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); 377 PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS);
374 } 378 }
375 379
376 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( 380 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
377 bool is_tail_call) { 381 bool is_tail_call) {
378 // Pretend that the exit is a backwards jump to the entry. 382 // Pretend that the exit is a backwards jump to the entry.
379 int weight = 1; 383 int weight = 1;
380 if (info_->ShouldSelfOptimize()) { 384 if (info_->ShouldSelfOptimize()) {
381 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 385 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
382 } else { 386 } else {
383 int distance = masm_->pc_offset(); 387 int distance = masm_->pc_offset();
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 bool should_normalize, 674 bool should_normalize,
671 Label* if_true, 675 Label* if_true,
672 Label* if_false) { 676 Label* if_false) {
673 // Only prepare for bailouts before splits if we're in a test 677 // Only prepare for bailouts before splits if we're in a test
674 // context. Otherwise, we let the Visit function deal with the 678 // context. Otherwise, we let the Visit function deal with the
675 // preparation to avoid preparing with the same AST id twice. 679 // preparation to avoid preparing with the same AST id twice.
676 if (!context()->IsTest()) return; 680 if (!context()->IsTest()) return;
677 681
678 Label skip; 682 Label skip;
679 if (should_normalize) __ jmp(&skip, Label::kNear); 683 if (should_normalize) __ jmp(&skip, Label::kNear);
680 PrepareForBailout(expr, TOS_REG); 684 PrepareForBailout(expr, BailoutState::TOS_REGISTER);
681 if (should_normalize) { 685 if (should_normalize) {
682 __ cmp(eax, isolate()->factory()->true_value()); 686 __ cmp(eax, isolate()->factory()->true_value());
683 Split(equal, if_true, if_false, NULL); 687 Split(equal, if_true, if_false, NULL);
684 __ bind(&skip); 688 __ bind(&skip);
685 } 689 }
686 } 690 }
687 691
688 692
689 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 693 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
690 // The variable in the declaration always resides in the current context. 694 // The variable in the declaration always resides in the current context.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 } 730 }
727 break; 731 break;
728 732
729 case VariableLocation::CONTEXT: 733 case VariableLocation::CONTEXT:
730 if (hole_init) { 734 if (hole_init) {
731 Comment cmnt(masm_, "[ VariableDeclaration"); 735 Comment cmnt(masm_, "[ VariableDeclaration");
732 EmitDebugCheckDeclarationContext(variable); 736 EmitDebugCheckDeclarationContext(variable);
733 __ mov(ContextOperand(esi, variable->index()), 737 __ mov(ContextOperand(esi, variable->index()),
734 Immediate(isolate()->factory()->the_hole_value())); 738 Immediate(isolate()->factory()->the_hole_value()));
735 // No write barrier since the hole value is in old space. 739 // No write barrier since the hole value is in old space.
736 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 740 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
737 } 741 }
738 break; 742 break;
739 743
740 case VariableLocation::LOOKUP: { 744 case VariableLocation::LOOKUP: {
741 Comment cmnt(masm_, "[ VariableDeclaration"); 745 Comment cmnt(masm_, "[ VariableDeclaration");
742 __ push(Immediate(variable->name())); 746 __ push(Immediate(variable->name()));
743 // VariableDeclaration nodes are always introduced in one of four modes. 747 // VariableDeclaration nodes are always introduced in one of four modes.
744 DCHECK(IsDeclaredVariableMode(mode)); 748 DCHECK(IsDeclaredVariableMode(mode));
745 // Push initial value, if any. 749 // Push initial value, if any.
746 // Note: For variables we must not push an initial value (such as 750 // Note: For variables we must not push an initial value (such as
747 // 'undefined') because we may have a (legal) redeclaration and we 751 // 'undefined') because we may have a (legal) redeclaration and we
748 // must not destroy the current value. 752 // must not destroy the current value.
749 if (hole_init) { 753 if (hole_init) {
750 __ push(Immediate(isolate()->factory()->the_hole_value())); 754 __ push(Immediate(isolate()->factory()->the_hole_value()));
751 } else { 755 } else {
752 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. 756 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value.
753 } 757 }
754 __ push( 758 __ push(
755 Immediate(Smi::FromInt(variable->DeclarationPropertyAttributes()))); 759 Immediate(Smi::FromInt(variable->DeclarationPropertyAttributes())));
756 __ CallRuntime(Runtime::kDeclareLookupSlot); 760 __ CallRuntime(Runtime::kDeclareLookupSlot);
757 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 761 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
758 break; 762 break;
759 } 763 }
760 } 764 }
761 } 765 }
762 766
763 void FullCodeGenerator::VisitFunctionDeclaration( 767 void FullCodeGenerator::VisitFunctionDeclaration(
764 FunctionDeclaration* declaration) { 768 FunctionDeclaration* declaration) {
765 VariableProxy* proxy = declaration->proxy(); 769 VariableProxy* proxy = declaration->proxy();
766 Variable* variable = proxy->var(); 770 Variable* variable = proxy->var();
767 switch (variable->location()) { 771 switch (variable->location()) {
(...skipping 18 matching lines...) Expand all
786 790
787 case VariableLocation::CONTEXT: { 791 case VariableLocation::CONTEXT: {
788 Comment cmnt(masm_, "[ FunctionDeclaration"); 792 Comment cmnt(masm_, "[ FunctionDeclaration");
789 EmitDebugCheckDeclarationContext(variable); 793 EmitDebugCheckDeclarationContext(variable);
790 VisitForAccumulatorValue(declaration->fun()); 794 VisitForAccumulatorValue(declaration->fun());
791 __ mov(ContextOperand(esi, variable->index()), result_register()); 795 __ mov(ContextOperand(esi, variable->index()), result_register());
792 // We know that we have written a function, which is not a smi. 796 // We know that we have written a function, which is not a smi.
793 __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()), 797 __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()),
794 result_register(), ecx, kDontSaveFPRegs, 798 result_register(), ecx, kDontSaveFPRegs,
795 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 799 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
796 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 800 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
797 break; 801 break;
798 } 802 }
799 803
800 case VariableLocation::LOOKUP: { 804 case VariableLocation::LOOKUP: {
801 Comment cmnt(masm_, "[ FunctionDeclaration"); 805 Comment cmnt(masm_, "[ FunctionDeclaration");
802 PushOperand(variable->name()); 806 PushOperand(variable->name());
803 VisitForStackValue(declaration->fun()); 807 VisitForStackValue(declaration->fun());
804 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); 808 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
805 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); 809 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
806 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 810 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
807 break; 811 break;
808 } 812 }
809 } 813 }
810 } 814 }
811 815
812 816
813 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 817 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
814 // Call the runtime to declare the globals. 818 // Call the runtime to declare the globals.
815 __ Push(pairs); 819 __ Push(pairs);
816 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 820 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 10 matching lines...) Expand all
827 } 831 }
828 832
829 833
830 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 834 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
831 Comment cmnt(masm_, "[ SwitchStatement"); 835 Comment cmnt(masm_, "[ SwitchStatement");
832 Breakable nested_statement(this, stmt); 836 Breakable nested_statement(this, stmt);
833 SetStatementPosition(stmt); 837 SetStatementPosition(stmt);
834 838
835 // Keep the switch value on the stack until a case matches. 839 // Keep the switch value on the stack until a case matches.
836 VisitForStackValue(stmt->tag()); 840 VisitForStackValue(stmt->tag());
837 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 841 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
838 842
839 ZoneList<CaseClause*>* clauses = stmt->cases(); 843 ZoneList<CaseClause*>* clauses = stmt->cases();
840 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 844 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
841 845
842 Label next_test; // Recycled for each test. 846 Label next_test; // Recycled for each test.
843 // Compile all the tests with branches to their bodies. 847 // Compile all the tests with branches to their bodies.
844 for (int i = 0; i < clauses->length(); i++) { 848 for (int i = 0; i < clauses->length(); i++) {
845 CaseClause* clause = clauses->at(i); 849 CaseClause* clause = clauses->at(i);
846 clause->body_target()->Unuse(); 850 clause->body_target()->Unuse();
847 851
(...skipping 28 matching lines...) Expand all
876 } 880 }
877 881
878 SetExpressionPosition(clause); 882 SetExpressionPosition(clause);
879 Handle<Code> ic = 883 Handle<Code> ic =
880 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); 884 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
881 CallIC(ic, clause->CompareId()); 885 CallIC(ic, clause->CompareId());
882 patch_site.EmitPatchInfo(); 886 patch_site.EmitPatchInfo();
883 887
884 Label skip; 888 Label skip;
885 __ jmp(&skip, Label::kNear); 889 __ jmp(&skip, Label::kNear);
886 PrepareForBailout(clause, TOS_REG); 890 PrepareForBailout(clause, BailoutState::TOS_REGISTER);
887 __ cmp(eax, isolate()->factory()->true_value()); 891 __ cmp(eax, isolate()->factory()->true_value());
888 __ j(not_equal, &next_test); 892 __ j(not_equal, &next_test);
889 __ Drop(1); 893 __ Drop(1);
890 __ jmp(clause->body_target()); 894 __ jmp(clause->body_target());
891 __ bind(&skip); 895 __ bind(&skip);
892 896
893 __ test(eax, eax); 897 __ test(eax, eax);
894 __ j(not_equal, &next_test); 898 __ j(not_equal, &next_test);
895 __ Drop(1); // Switch value is no longer needed. 899 __ Drop(1); // Switch value is no longer needed.
896 __ jmp(clause->body_target()); 900 __ jmp(clause->body_target());
897 } 901 }
898 902
899 // Discard the test value and jump to the default if present, otherwise to 903 // Discard the test value and jump to the default if present, otherwise to
900 // the end of the statement. 904 // the end of the statement.
901 __ bind(&next_test); 905 __ bind(&next_test);
902 DropOperands(1); // Switch value is no longer needed. 906 DropOperands(1); // Switch value is no longer needed.
903 if (default_clause == NULL) { 907 if (default_clause == NULL) {
904 __ jmp(nested_statement.break_label()); 908 __ jmp(nested_statement.break_label());
905 } else { 909 } else {
906 __ jmp(default_clause->body_target()); 910 __ jmp(default_clause->body_target());
907 } 911 }
908 912
909 // Compile all the case bodies. 913 // Compile all the case bodies.
910 for (int i = 0; i < clauses->length(); i++) { 914 for (int i = 0; i < clauses->length(); i++) {
911 Comment cmnt(masm_, "[ Case body"); 915 Comment cmnt(masm_, "[ Case body");
912 CaseClause* clause = clauses->at(i); 916 CaseClause* clause = clauses->at(i);
913 __ bind(clause->body_target()); 917 __ bind(clause->body_target());
914 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 918 PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS);
915 VisitStatements(clause->statements()); 919 VisitStatements(clause->statements());
916 } 920 }
917 921
918 __ bind(nested_statement.break_label()); 922 __ bind(nested_statement.break_label());
919 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 923 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
920 } 924 }
921 925
922 926
923 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 927 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
924 Comment cmnt(masm_, "[ ForInStatement"); 928 Comment cmnt(masm_, "[ ForInStatement");
925 SetStatementPosition(stmt, SKIP_BREAK); 929 SetStatementPosition(stmt, SKIP_BREAK);
926 930
927 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 931 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
928 932
929 // Get the object to enumerate over. 933 // Get the object to enumerate over.
(...skipping 12 matching lines...) Expand all
942 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx); 946 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
943 __ j(above_equal, &done_convert, Label::kNear); 947 __ j(above_equal, &done_convert, Label::kNear);
944 __ cmp(eax, isolate()->factory()->undefined_value()); 948 __ cmp(eax, isolate()->factory()->undefined_value());
945 __ j(equal, &exit); 949 __ j(equal, &exit);
946 __ cmp(eax, isolate()->factory()->null_value()); 950 __ cmp(eax, isolate()->factory()->null_value());
947 __ j(equal, &exit); 951 __ j(equal, &exit);
948 __ bind(&convert); 952 __ bind(&convert);
949 ToObjectStub stub(isolate()); 953 ToObjectStub stub(isolate());
950 __ CallStub(&stub); 954 __ CallStub(&stub);
951 __ bind(&done_convert); 955 __ bind(&done_convert);
952 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); 956 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
953 __ push(eax); 957 __ push(eax);
954 958
955 // Check cache validity in generated code. If we cannot guarantee cache 959 // Check cache validity in generated code. If we cannot guarantee cache
956 // validity, call the runtime system to check cache validity or get the 960 // validity, call the runtime system to check cache validity or get the
957 // property names in a fixed array. Note: Proxies never have an enum cache, 961 // property names in a fixed array. Note: Proxies never have an enum cache,
958 // so will always take the slow path. 962 // so will always take the slow path.
959 Label call_runtime, use_cache, fixed_array; 963 Label call_runtime, use_cache, fixed_array;
960 __ CheckEnumCache(&call_runtime); 964 __ CheckEnumCache(&call_runtime);
961 965
962 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); 966 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
963 __ jmp(&use_cache, Label::kNear); 967 __ jmp(&use_cache, Label::kNear);
964 968
965 // Get the set of properties to enumerate. 969 // Get the set of properties to enumerate.
966 __ bind(&call_runtime); 970 __ bind(&call_runtime);
967 __ push(eax); 971 __ push(eax);
968 __ CallRuntime(Runtime::kForInEnumerate); 972 __ CallRuntime(Runtime::kForInEnumerate);
969 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 973 PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER);
970 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 974 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
971 isolate()->factory()->meta_map()); 975 isolate()->factory()->meta_map());
972 __ j(not_equal, &fixed_array); 976 __ j(not_equal, &fixed_array);
973 977
974 978
975 // We got a map in register eax. Get the enumeration cache from it. 979 // We got a map in register eax. Get the enumeration cache from it.
976 Label no_descriptors; 980 Label no_descriptors;
977 __ bind(&use_cache); 981 __ bind(&use_cache);
978 982
979 __ EnumLength(edx, eax); 983 __ EnumLength(edx, eax);
(...skipping 11 matching lines...) Expand all
991 __ push(Immediate(Smi::FromInt(0))); // Initial index. 995 __ push(Immediate(Smi::FromInt(0))); // Initial index.
992 __ jmp(&loop); 996 __ jmp(&loop);
993 997
994 __ bind(&no_descriptors); 998 __ bind(&no_descriptors);
995 __ add(esp, Immediate(kPointerSize)); 999 __ add(esp, Immediate(kPointerSize));
996 __ jmp(&exit); 1000 __ jmp(&exit);
997 1001
998 // We got a fixed array in register eax. Iterate through that. 1002 // We got a fixed array in register eax. Iterate through that.
999 __ bind(&fixed_array); 1003 __ bind(&fixed_array);
1000 1004
1001 __ push(Immediate(Smi::FromInt(1))); // Smi(1) undicates slow check 1005 __ push(Immediate(Smi::FromInt(1))); // Smi(1) indicates slow check
1002 __ push(eax); // Array 1006 __ push(eax); // Array
1003 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); 1007 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset));
1004 __ push(eax); // Fixed array length (as smi). 1008 __ push(eax); // Fixed array length (as smi).
1005 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); 1009 PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS);
1006 __ push(Immediate(Smi::FromInt(0))); // Initial index. 1010 __ push(Immediate(Smi::FromInt(0))); // Initial index.
1007 1011
1008 // Generate code for doing the condition check. 1012 // Generate code for doing the condition check.
1009 __ bind(&loop); 1013 __ bind(&loop);
1010 SetExpressionAsStatementPosition(stmt->each()); 1014 SetExpressionAsStatementPosition(stmt->each());
1011 1015
1012 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. 1016 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index.
1013 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. 1017 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length.
1014 __ j(above_equal, loop_statement.break_label()); 1018 __ j(above_equal, loop_statement.break_label());
1015 1019
(...skipping 17 matching lines...) Expand all
1033 __ EmitLoadTypeFeedbackVector(edx); 1037 __ EmitLoadTypeFeedbackVector(edx);
1034 __ mov(FieldOperand(edx, FixedArray::OffsetOfElementAt(vector_index)), 1038 __ mov(FieldOperand(edx, FixedArray::OffsetOfElementAt(vector_index)),
1035 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 1039 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1036 1040
1037 // Convert the entry to a string or null if it isn't a property 1041 // Convert the entry to a string or null if it isn't a property
1038 // anymore. If the property has been removed while iterating, we 1042 // anymore. If the property has been removed while iterating, we
1039 // just skip it. 1043 // just skip it.
1040 __ push(ecx); // Enumerable. 1044 __ push(ecx); // Enumerable.
1041 __ push(ebx); // Current entry. 1045 __ push(ebx); // Current entry.
1042 __ CallRuntime(Runtime::kForInFilter); 1046 __ CallRuntime(Runtime::kForInFilter);
1043 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1047 PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
1044 __ cmp(eax, isolate()->factory()->undefined_value()); 1048 __ cmp(eax, isolate()->factory()->undefined_value());
1045 __ j(equal, loop_statement.continue_label()); 1049 __ j(equal, loop_statement.continue_label());
1046 __ mov(ebx, eax); 1050 __ mov(ebx, eax);
1047 1051
1048 // Update the 'each' property or variable from the possibly filtered 1052 // Update the 'each' property or variable from the possibly filtered
1049 // entry in register ebx. 1053 // entry in register ebx.
1050 __ bind(&update_each); 1054 __ bind(&update_each);
1051 __ mov(result_register(), ebx); 1055 __ mov(result_register(), ebx);
1052 // Perform the assignment as if via '='. 1056 // Perform the assignment as if via '='.
1053 { EffectContext context(this); 1057 { EffectContext context(this);
1054 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1058 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1055 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); 1059 PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS);
1056 } 1060 }
1057 1061
1058 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). 1062 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
1059 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1063 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
1060 // Generate code for the body of the loop. 1064 // Generate code for the body of the loop.
1061 Visit(stmt->body()); 1065 Visit(stmt->body());
1062 1066
1063 // Generate code for going to the next element by incrementing the 1067 // Generate code for going to the next element by incrementing the
1064 // index (smi) stored on top of the stack. 1068 // index (smi) stored on top of the stack.
1065 __ bind(loop_statement.continue_label()); 1069 __ bind(loop_statement.continue_label());
1066 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); 1070 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
1067 1071
1068 EmitBackEdgeBookkeeping(stmt, &loop); 1072 EmitBackEdgeBookkeeping(stmt, &loop);
1069 __ jmp(&loop); 1073 __ jmp(&loop);
1070 1074
1071 // Remove the pointers stored on the stack. 1075 // Remove the pointers stored on the stack.
1072 __ bind(loop_statement.break_label()); 1076 __ bind(loop_statement.break_label());
1073 DropOperands(5); 1077 DropOperands(5);
1074 1078
1075 // Exit and decrement the loop depth. 1079 // Exit and decrement the loop depth.
1076 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1080 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
1077 __ bind(&exit); 1081 __ bind(&exit);
1078 decrement_loop_depth(); 1082 decrement_loop_depth();
1079 } 1083 }
1080 1084
1081 1085
1082 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1086 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1083 FeedbackVectorSlot slot) { 1087 FeedbackVectorSlot slot) {
1084 DCHECK(NeedsHomeObject(initializer)); 1088 DCHECK(NeedsHomeObject(initializer));
1085 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1089 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1086 __ mov(StoreDescriptor::NameRegister(), 1090 __ mov(StoreDescriptor::NameRegister(),
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 __ mov(LoadDescriptor::NameRegister(), var->name()); 1228 __ mov(LoadDescriptor::NameRegister(), var->name());
1225 __ mov(LoadDescriptor::SlotRegister(), 1229 __ mov(LoadDescriptor::SlotRegister(),
1226 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot()))); 1230 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
1227 CallLoadIC(typeof_mode); 1231 CallLoadIC(typeof_mode);
1228 } 1232 }
1229 1233
1230 1234
1231 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1235 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1232 TypeofMode typeof_mode) { 1236 TypeofMode typeof_mode) {
1233 SetExpressionPosition(proxy); 1237 SetExpressionPosition(proxy);
1234 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1238 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1235 Variable* var = proxy->var(); 1239 Variable* var = proxy->var();
1236 1240
1237 // Three cases: global variables, lookup variables, and all other types of 1241 // Three cases: global variables, lookup variables, and all other types of
1238 // variables. 1242 // variables.
1239 switch (var->location()) { 1243 switch (var->location()) {
1240 case VariableLocation::GLOBAL: 1244 case VariableLocation::GLOBAL:
1241 case VariableLocation::UNALLOCATED: { 1245 case VariableLocation::UNALLOCATED: {
1242 Comment cmnt(masm_, "[ Global variable"); 1246 Comment cmnt(masm_, "[ Global variable");
1243 EmitGlobalVariableLoad(proxy, typeof_mode); 1247 EmitGlobalVariableLoad(proxy, typeof_mode);
1244 context()->Plug(eax); 1248 context()->Plug(eax);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 __ CallRuntime(Runtime::kCreateObjectLiteral); 1340 __ CallRuntime(Runtime::kCreateObjectLiteral);
1337 } else { 1341 } else {
1338 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1342 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1339 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); 1343 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index())));
1340 __ mov(ecx, Immediate(constant_properties)); 1344 __ mov(ecx, Immediate(constant_properties));
1341 __ mov(edx, Immediate(Smi::FromInt(flags))); 1345 __ mov(edx, Immediate(Smi::FromInt(flags)));
1342 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1346 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1343 __ CallStub(&stub); 1347 __ CallStub(&stub);
1344 RestoreContext(); 1348 RestoreContext();
1345 } 1349 }
1346 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1350 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
1347 1351
1348 // If result_saved is true the result is on top of the stack. If 1352 // If result_saved is true the result is on top of the stack. If
1349 // result_saved is false the result is in eax. 1353 // result_saved is false the result is in eax.
1350 bool result_saved = false; 1354 bool result_saved = false;
1351 1355
1352 AccessorTable accessor_table(zone()); 1356 AccessorTable accessor_table(zone());
1353 int property_index = 0; 1357 int property_index = 0;
1354 for (; property_index < expr->properties()->length(); property_index++) { 1358 for (; property_index < expr->properties()->length(); property_index++) {
1355 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1359 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1356 if (property->is_computed_name()) break; 1360 if (property->is_computed_name()) break;
(...skipping 15 matching lines...) Expand all
1372 // It is safe to use [[Put]] here because the boilerplate already 1376 // It is safe to use [[Put]] here because the boilerplate already
1373 // contains computed properties with an uninitialized value. 1377 // contains computed properties with an uninitialized value.
1374 if (key->value()->IsInternalizedString()) { 1378 if (key->value()->IsInternalizedString()) {
1375 if (property->emit_store()) { 1379 if (property->emit_store()) {
1376 VisitForAccumulatorValue(value); 1380 VisitForAccumulatorValue(value);
1377 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 1381 DCHECK(StoreDescriptor::ValueRegister().is(eax));
1378 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); 1382 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value()));
1379 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1383 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1380 EmitLoadStoreICSlot(property->GetSlot(0)); 1384 EmitLoadStoreICSlot(property->GetSlot(0));
1381 CallStoreIC(); 1385 CallStoreIC();
1382 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1386 PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS);
1383 if (NeedsHomeObject(value)) { 1387 if (NeedsHomeObject(value)) {
1384 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1388 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1385 } 1389 }
1386 } else { 1390 } else {
1387 VisitForEffect(value); 1391 VisitForEffect(value);
1388 } 1392 }
1389 break; 1393 break;
1390 } 1394 }
1391 PushOperand(Operand(esp, 0)); // Duplicate receiver. 1395 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1392 VisitForStackValue(key); 1396 VisitForStackValue(key);
1393 VisitForStackValue(value); 1397 VisitForStackValue(value);
1394 if (property->emit_store()) { 1398 if (property->emit_store()) {
1395 if (NeedsHomeObject(value)) { 1399 if (NeedsHomeObject(value)) {
1396 EmitSetHomeObject(value, 2, property->GetSlot()); 1400 EmitSetHomeObject(value, 2, property->GetSlot());
1397 } 1401 }
1398 PushOperand(Smi::FromInt(SLOPPY)); // Language mode 1402 PushOperand(Smi::FromInt(SLOPPY)); // Language mode
1399 CallRuntimeWithOperands(Runtime::kSetProperty); 1403 CallRuntimeWithOperands(Runtime::kSetProperty);
1400 } else { 1404 } else {
1401 DropOperands(3); 1405 DropOperands(3);
1402 } 1406 }
1403 break; 1407 break;
1404 case ObjectLiteral::Property::PROTOTYPE: 1408 case ObjectLiteral::Property::PROTOTYPE:
1405 PushOperand(Operand(esp, 0)); // Duplicate receiver. 1409 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1406 VisitForStackValue(value); 1410 VisitForStackValue(value);
1407 DCHECK(property->emit_store()); 1411 DCHECK(property->emit_store());
1408 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1412 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1409 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1413 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1410 NO_REGISTERS); 1414 BailoutState::NO_REGISTERS);
1411 break; 1415 break;
1412 case ObjectLiteral::Property::GETTER: 1416 case ObjectLiteral::Property::GETTER:
1413 if (property->emit_store()) { 1417 if (property->emit_store()) {
1414 accessor_table.lookup(key)->second->getter = property; 1418 accessor_table.lookup(key)->second->getter = property;
1415 } 1419 }
1416 break; 1420 break;
1417 case ObjectLiteral::Property::SETTER: 1421 case ObjectLiteral::Property::SETTER:
1418 if (property->emit_store()) { 1422 if (property->emit_store()) {
1419 accessor_table.lookup(key)->second->setter = property; 1423 accessor_table.lookup(key)->second->setter = property;
1420 } 1424 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 } 1460 }
1457 1461
1458 PushOperand(Operand(esp, 0)); // Duplicate receiver. 1462 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1459 1463
1460 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1464 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1461 DCHECK(!property->is_computed_name()); 1465 DCHECK(!property->is_computed_name());
1462 VisitForStackValue(value); 1466 VisitForStackValue(value);
1463 DCHECK(property->emit_store()); 1467 DCHECK(property->emit_store());
1464 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1468 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1465 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1469 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1466 NO_REGISTERS); 1470 BailoutState::NO_REGISTERS);
1467 } else { 1471 } else {
1468 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1472 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1469 VisitForStackValue(value); 1473 VisitForStackValue(value);
1470 if (NeedsHomeObject(value)) { 1474 if (NeedsHomeObject(value)) {
1471 EmitSetHomeObject(value, 2, property->GetSlot()); 1475 EmitSetHomeObject(value, 2, property->GetSlot());
1472 } 1476 }
1473 1477
1474 switch (property->kind()) { 1478 switch (property->kind()) {
1475 case ObjectLiteral::Property::CONSTANT: 1479 case ObjectLiteral::Property::CONSTANT:
1476 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1480 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 __ push(Immediate(constant_elements)); 1533 __ push(Immediate(constant_elements));
1530 __ push(Immediate(Smi::FromInt(expr->ComputeFlags()))); 1534 __ push(Immediate(Smi::FromInt(expr->ComputeFlags())));
1531 __ CallRuntime(Runtime::kCreateArrayLiteral); 1535 __ CallRuntime(Runtime::kCreateArrayLiteral);
1532 } else { 1536 } else {
1533 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1537 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1534 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); 1538 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index())));
1535 __ mov(ecx, Immediate(constant_elements)); 1539 __ mov(ecx, Immediate(constant_elements));
1536 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1540 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1537 __ CallStub(&stub); 1541 __ CallStub(&stub);
1538 } 1542 }
1539 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1543 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
1540 1544
1541 bool result_saved = false; // Is the result saved to the stack? 1545 bool result_saved = false; // Is the result saved to the stack?
1542 ZoneList<Expression*>* subexprs = expr->values(); 1546 ZoneList<Expression*>* subexprs = expr->values();
1543 int length = subexprs->length(); 1547 int length = subexprs->length();
1544 1548
1545 // Emit code to evaluate all the non-constant subexpressions and to store 1549 // Emit code to evaluate all the non-constant subexpressions and to store
1546 // them into the newly cloned array. 1550 // them into the newly cloned array.
1547 int array_index = 0; 1551 int array_index = 0;
1548 for (; array_index < length; array_index++) { 1552 for (; array_index < length; array_index++) {
1549 Expression* subexpr = subexprs->at(array_index); 1553 Expression* subexpr = subexprs->at(array_index);
1550 DCHECK(!subexpr->IsSpread()); 1554 DCHECK(!subexpr->IsSpread());
1551 1555
1552 // If the subexpression is a literal or a simple materialized literal it 1556 // If the subexpression is a literal or a simple materialized literal it
1553 // is already set in the cloned array. 1557 // is already set in the cloned array.
1554 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1558 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1555 1559
1556 if (!result_saved) { 1560 if (!result_saved) {
1557 PushOperand(eax); // array literal. 1561 PushOperand(eax); // array literal.
1558 result_saved = true; 1562 result_saved = true;
1559 } 1563 }
1560 VisitForAccumulatorValue(subexpr); 1564 VisitForAccumulatorValue(subexpr);
1561 1565
1562 __ mov(StoreDescriptor::NameRegister(), 1566 __ mov(StoreDescriptor::NameRegister(),
1563 Immediate(Smi::FromInt(array_index))); 1567 Immediate(Smi::FromInt(array_index)));
1564 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1568 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1565 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1569 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1566 Handle<Code> ic = 1570 Handle<Code> ic =
1567 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1571 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1568 CallIC(ic); 1572 CallIC(ic);
1569 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1573 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1574 BailoutState::NO_REGISTERS);
1570 } 1575 }
1571 1576
1572 // In case the array literal contains spread expressions it has two parts. The 1577 // In case the array literal contains spread expressions it has two parts. The
1573 // first part is the "static" array which has a literal index is handled 1578 // first part is the "static" array which has a literal index is handled
1574 // above. The second part is the part after the first spread expression 1579 // above. The second part is the part after the first spread expression
1575 // (inclusive) and these elements gets appended to the array. Note that the 1580 // (inclusive) and these elements gets appended to the array. Note that the
1576 // number elements an iterable produces is unknown ahead of time. 1581 // number elements an iterable produces is unknown ahead of time.
1577 if (array_index < length && result_saved) { 1582 if (array_index < length && result_saved) {
1578 PopOperand(eax); 1583 PopOperand(eax);
1579 result_saved = false; 1584 result_saved = false;
1580 } 1585 }
1581 for (; array_index < length; array_index++) { 1586 for (; array_index < length; array_index++) {
1582 Expression* subexpr = subexprs->at(array_index); 1587 Expression* subexpr = subexprs->at(array_index);
1583 1588
1584 PushOperand(eax); 1589 PushOperand(eax);
1585 DCHECK(!subexpr->IsSpread()); 1590 DCHECK(!subexpr->IsSpread());
1586 VisitForStackValue(subexpr); 1591 VisitForStackValue(subexpr);
1587 CallRuntimeWithOperands(Runtime::kAppendElement); 1592 CallRuntimeWithOperands(Runtime::kAppendElement);
1588 1593
1589 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1594 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1595 BailoutState::NO_REGISTERS);
1590 } 1596 }
1591 1597
1592 if (result_saved) { 1598 if (result_saved) {
1593 context()->PlugTOS(); 1599 context()->PlugTOS();
1594 } else { 1600 } else {
1595 context()->Plug(eax); 1601 context()->Plug(eax);
1596 } 1602 }
1597 } 1603 }
1598 1604
1599 1605
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1658 } 1664 }
1659 1665
1660 // For compound assignments we need another deoptimization point after the 1666 // For compound assignments we need another deoptimization point after the
1661 // variable/property load. 1667 // variable/property load.
1662 if (expr->is_compound()) { 1668 if (expr->is_compound()) {
1663 AccumulatorValueContext result_context(this); 1669 AccumulatorValueContext result_context(this);
1664 { AccumulatorValueContext left_operand_context(this); 1670 { AccumulatorValueContext left_operand_context(this);
1665 switch (assign_type) { 1671 switch (assign_type) {
1666 case VARIABLE: 1672 case VARIABLE:
1667 EmitVariableLoad(expr->target()->AsVariableProxy()); 1673 EmitVariableLoad(expr->target()->AsVariableProxy());
1668 PrepareForBailout(expr->target(), TOS_REG); 1674 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER);
1669 break; 1675 break;
1670 case NAMED_SUPER_PROPERTY: 1676 case NAMED_SUPER_PROPERTY:
1671 EmitNamedSuperPropertyLoad(property); 1677 EmitNamedSuperPropertyLoad(property);
1672 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1678 PrepareForBailoutForId(property->LoadId(),
1679 BailoutState::TOS_REGISTER);
1673 break; 1680 break;
1674 case NAMED_PROPERTY: 1681 case NAMED_PROPERTY:
1675 EmitNamedPropertyLoad(property); 1682 EmitNamedPropertyLoad(property);
1676 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1683 PrepareForBailoutForId(property->LoadId(),
1684 BailoutState::TOS_REGISTER);
1677 break; 1685 break;
1678 case KEYED_SUPER_PROPERTY: 1686 case KEYED_SUPER_PROPERTY:
1679 EmitKeyedSuperPropertyLoad(property); 1687 EmitKeyedSuperPropertyLoad(property);
1680 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1688 PrepareForBailoutForId(property->LoadId(),
1689 BailoutState::TOS_REGISTER);
1681 break; 1690 break;
1682 case KEYED_PROPERTY: 1691 case KEYED_PROPERTY:
1683 EmitKeyedPropertyLoad(property); 1692 EmitKeyedPropertyLoad(property);
1684 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1693 PrepareForBailoutForId(property->LoadId(),
1694 BailoutState::TOS_REGISTER);
1685 break; 1695 break;
1686 } 1696 }
1687 } 1697 }
1688 1698
1689 Token::Value op = expr->binary_op(); 1699 Token::Value op = expr->binary_op();
1690 PushOperand(eax); // Left operand goes on the stack. 1700 PushOperand(eax); // Left operand goes on the stack.
1691 VisitForAccumulatorValue(expr->value()); 1701 VisitForAccumulatorValue(expr->value());
1692 1702
1693 if (ShouldInlineSmiCase(op)) { 1703 if (ShouldInlineSmiCase(op)) {
1694 EmitInlineSmiBinaryOp(expr->binary_operation(), 1704 EmitInlineSmiBinaryOp(expr->binary_operation(),
1695 op, 1705 op,
1696 expr->target(), 1706 expr->target(),
1697 expr->value()); 1707 expr->value());
1698 } else { 1708 } else {
1699 EmitBinaryOp(expr->binary_operation(), op); 1709 EmitBinaryOp(expr->binary_operation(), op);
1700 } 1710 }
1701 1711
1702 // Deoptimization point in case the binary operation may have side effects. 1712 // Deoptimization point in case the binary operation may have side effects.
1703 PrepareForBailout(expr->binary_operation(), TOS_REG); 1713 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER);
1704 } else { 1714 } else {
1705 VisitForAccumulatorValue(expr->value()); 1715 VisitForAccumulatorValue(expr->value());
1706 } 1716 }
1707 1717
1708 SetExpressionPosition(expr); 1718 SetExpressionPosition(expr);
1709 1719
1710 // Store the value. 1720 // Store the value.
1711 switch (assign_type) { 1721 switch (assign_type) {
1712 case VARIABLE: 1722 case VARIABLE:
1713 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1723 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1714 expr->op(), expr->AssignmentSlot()); 1724 expr->op(), expr->AssignmentSlot());
1715 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1725 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1716 context()->Plug(eax); 1726 context()->Plug(eax);
1717 break; 1727 break;
1718 case NAMED_PROPERTY: 1728 case NAMED_PROPERTY:
1719 EmitNamedPropertyAssignment(expr); 1729 EmitNamedPropertyAssignment(expr);
1720 break; 1730 break;
1721 case NAMED_SUPER_PROPERTY: 1731 case NAMED_SUPER_PROPERTY:
1722 EmitNamedSuperPropertyStore(property); 1732 EmitNamedSuperPropertyStore(property);
1723 context()->Plug(result_register()); 1733 context()->Plug(result_register());
1724 break; 1734 break;
1725 case KEYED_SUPER_PROPERTY: 1735 case KEYED_SUPER_PROPERTY:
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
2164 // eax : value 2174 // eax : value
2165 // esp[0] : receiver 2175 // esp[0] : receiver
2166 Property* prop = expr->target()->AsProperty(); 2176 Property* prop = expr->target()->AsProperty();
2167 DCHECK(prop != NULL); 2177 DCHECK(prop != NULL);
2168 DCHECK(prop->key()->IsLiteral()); 2178 DCHECK(prop->key()->IsLiteral());
2169 2179
2170 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); 2180 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2171 PopOperand(StoreDescriptor::ReceiverRegister()); 2181 PopOperand(StoreDescriptor::ReceiverRegister());
2172 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2182 EmitLoadStoreICSlot(expr->AssignmentSlot());
2173 CallStoreIC(); 2183 CallStoreIC();
2174 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2184 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2175 context()->Plug(eax); 2185 context()->Plug(eax);
2176 } 2186 }
2177 2187
2178 2188
2179 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2189 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2180 // Assignment to named property of super. 2190 // Assignment to named property of super.
2181 // eax : value 2191 // eax : value
2182 // stack : receiver ('this'), home_object 2192 // stack : receiver ('this'), home_object
2183 DCHECK(prop != NULL); 2193 DCHECK(prop != NULL);
2184 Literal* key = prop->key()->AsLiteral(); 2194 Literal* key = prop->key()->AsLiteral();
(...skipping 25 matching lines...) Expand all
2210 // esp[0] : key 2220 // esp[0] : key
2211 // esp[kPointerSize] : receiver 2221 // esp[kPointerSize] : receiver
2212 2222
2213 PopOperand(StoreDescriptor::NameRegister()); // Key. 2223 PopOperand(StoreDescriptor::NameRegister()); // Key.
2214 PopOperand(StoreDescriptor::ReceiverRegister()); 2224 PopOperand(StoreDescriptor::ReceiverRegister());
2215 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 2225 DCHECK(StoreDescriptor::ValueRegister().is(eax));
2216 Handle<Code> ic = 2226 Handle<Code> ic =
2217 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2227 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2218 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2228 EmitLoadStoreICSlot(expr->AssignmentSlot());
2219 CallIC(ic); 2229 CallIC(ic);
2220 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2230 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2221 context()->Plug(eax); 2231 context()->Plug(eax);
2222 } 2232 }
2223 2233
2224 2234
2225 void FullCodeGenerator::CallIC(Handle<Code> code, 2235 void FullCodeGenerator::CallIC(Handle<Code> code,
2226 TypeFeedbackId ast_id) { 2236 TypeFeedbackId ast_id) {
2227 ic_total_count_++; 2237 ic_total_count_++;
2228 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2238 __ call(code, RelocInfo::CODE_TARGET, ast_id);
2229 } 2239 }
2230 2240
2231 2241
2232 // Code common for calls using the IC. 2242 // Code common for calls using the IC.
2233 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2243 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2234 Expression* callee = expr->expression(); 2244 Expression* callee = expr->expression();
2235 2245
2236 // Get the target function. 2246 // Get the target function.
2237 ConvertReceiverMode convert_mode; 2247 ConvertReceiverMode convert_mode;
2238 if (callee->IsVariableProxy()) { 2248 if (callee->IsVariableProxy()) {
2239 { StackValueContext context(this); 2249 { StackValueContext context(this);
2240 EmitVariableLoad(callee->AsVariableProxy()); 2250 EmitVariableLoad(callee->AsVariableProxy());
2241 PrepareForBailout(callee, NO_REGISTERS); 2251 PrepareForBailout(callee, BailoutState::NO_REGISTERS);
2242 } 2252 }
2243 // Push undefined as receiver. This is patched in the method prologue if it 2253 // Push undefined as receiver. This is patched in the method prologue if it
2244 // is a sloppy mode method. 2254 // is a sloppy mode method.
2245 PushOperand(isolate()->factory()->undefined_value()); 2255 PushOperand(isolate()->factory()->undefined_value());
2246 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2256 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2247 } else { 2257 } else {
2248 // Load the function from the receiver. 2258 // Load the function from the receiver.
2249 DCHECK(callee->IsProperty()); 2259 DCHECK(callee->IsProperty());
2250 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2260 DCHECK(!callee->AsProperty()->IsSuperAccess());
2251 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 2261 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2252 EmitNamedPropertyLoad(callee->AsProperty()); 2262 EmitNamedPropertyLoad(callee->AsProperty());
2253 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2263 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2264 BailoutState::TOS_REGISTER);
2254 // Push the target function under the receiver. 2265 // Push the target function under the receiver.
2255 PushOperand(Operand(esp, 0)); 2266 PushOperand(Operand(esp, 0));
2256 __ mov(Operand(esp, kPointerSize), eax); 2267 __ mov(Operand(esp, kPointerSize), eax);
2257 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2268 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2258 } 2269 }
2259 2270
2260 EmitCall(expr, convert_mode); 2271 EmitCall(expr, convert_mode);
2261 } 2272 }
2262 2273
2263 2274
(...skipping 14 matching lines...) Expand all
2278 PushOperand(eax); 2289 PushOperand(eax);
2279 PushOperand(Operand(esp, kPointerSize * 2)); 2290 PushOperand(Operand(esp, kPointerSize * 2));
2280 PushOperand(key->value()); 2291 PushOperand(key->value());
2281 // Stack here: 2292 // Stack here:
2282 // - home_object 2293 // - home_object
2283 // - this (receiver) 2294 // - this (receiver)
2284 // - this (receiver) <-- LoadFromSuper will pop here and below. 2295 // - this (receiver) <-- LoadFromSuper will pop here and below.
2285 // - home_object 2296 // - home_object
2286 // - key 2297 // - key
2287 CallRuntimeWithOperands(Runtime::kLoadFromSuper); 2298 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2288 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2299 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2289 2300
2290 // Replace home_object with target function. 2301 // Replace home_object with target function.
2291 __ mov(Operand(esp, kPointerSize), eax); 2302 __ mov(Operand(esp, kPointerSize), eax);
2292 2303
2293 // Stack here: 2304 // Stack here:
2294 // - target function 2305 // - target function
2295 // - this (receiver) 2306 // - this (receiver)
2296 EmitCall(expr); 2307 EmitCall(expr);
2297 } 2308 }
2298 2309
2299 2310
2300 // Code common for calls using the IC. 2311 // Code common for calls using the IC.
2301 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2312 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2302 Expression* key) { 2313 Expression* key) {
2303 // Load the key. 2314 // Load the key.
2304 VisitForAccumulatorValue(key); 2315 VisitForAccumulatorValue(key);
2305 2316
2306 Expression* callee = expr->expression(); 2317 Expression* callee = expr->expression();
2307 2318
2308 // Load the function from the receiver. 2319 // Load the function from the receiver.
2309 DCHECK(callee->IsProperty()); 2320 DCHECK(callee->IsProperty());
2310 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 2321 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2311 __ mov(LoadDescriptor::NameRegister(), eax); 2322 __ mov(LoadDescriptor::NameRegister(), eax);
2312 EmitKeyedPropertyLoad(callee->AsProperty()); 2323 EmitKeyedPropertyLoad(callee->AsProperty());
2313 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2324 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2325 BailoutState::TOS_REGISTER);
2314 2326
2315 // Push the target function under the receiver. 2327 // Push the target function under the receiver.
2316 PushOperand(Operand(esp, 0)); 2328 PushOperand(Operand(esp, 0));
2317 __ mov(Operand(esp, kPointerSize), eax); 2329 __ mov(Operand(esp, kPointerSize), eax);
2318 2330
2319 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2331 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2320 } 2332 }
2321 2333
2322 2334
2323 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2335 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
(...skipping 11 matching lines...) Expand all
2335 PushOperand(eax); 2347 PushOperand(eax);
2336 PushOperand(Operand(esp, kPointerSize * 2)); 2348 PushOperand(Operand(esp, kPointerSize * 2));
2337 VisitForStackValue(prop->key()); 2349 VisitForStackValue(prop->key());
2338 // Stack here: 2350 // Stack here:
2339 // - home_object 2351 // - home_object
2340 // - this (receiver) 2352 // - this (receiver)
2341 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2353 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2342 // - home_object 2354 // - home_object
2343 // - key 2355 // - key
2344 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); 2356 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2345 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2357 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2346 2358
2347 // Replace home_object with target function. 2359 // Replace home_object with target function.
2348 __ mov(Operand(esp, kPointerSize), eax); 2360 __ mov(Operand(esp, kPointerSize), eax);
2349 2361
2350 // Stack here: 2362 // Stack here:
2351 // - target function 2363 // - target function
2352 // - this (receiver) 2364 // - this (receiver)
2353 EmitCall(expr); 2365 EmitCall(expr);
2354 } 2366 }
2355 2367
2356 2368
2357 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { 2369 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
2358 // Load the arguments. 2370 // Load the arguments.
2359 ZoneList<Expression*>* args = expr->arguments(); 2371 ZoneList<Expression*>* args = expr->arguments();
2360 int arg_count = args->length(); 2372 int arg_count = args->length();
2361 for (int i = 0; i < arg_count; i++) { 2373 for (int i = 0; i < arg_count; i++) {
2362 VisitForStackValue(args->at(i)); 2374 VisitForStackValue(args->at(i));
2363 } 2375 }
2364 2376
2365 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2377 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
2366 SetCallPosition(expr, expr->tail_call_mode()); 2378 SetCallPosition(expr, expr->tail_call_mode());
2367 if (expr->tail_call_mode() == TailCallMode::kAllow) { 2379 if (expr->tail_call_mode() == TailCallMode::kAllow) {
2368 if (FLAG_trace) { 2380 if (FLAG_trace) {
2369 __ CallRuntime(Runtime::kTraceTailCall); 2381 __ CallRuntime(Runtime::kTraceTailCall);
2370 } 2382 }
2371 // Update profiling counters before the tail call since we will 2383 // Update profiling counters before the tail call since we will
2372 // not return to this function. 2384 // not return to this function.
2373 EmitProfilingCounterHandlingForReturnSequence(true); 2385 EmitProfilingCounterHandlingForReturnSequence(true);
2374 } 2386 }
2375 Handle<Code> ic = 2387 Handle<Code> ic =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2423 // eval-introduced variables. 2435 // eval-introduced variables.
2424 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2436 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2425 2437
2426 __ bind(&slow); 2438 __ bind(&slow);
2427 // Call the runtime to find the function to call (returned in eax) and 2439 // Call the runtime to find the function to call (returned in eax) and
2428 // the object holding it (returned in edx). 2440 // the object holding it (returned in edx).
2429 __ Push(callee->name()); 2441 __ Push(callee->name());
2430 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2442 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2431 PushOperand(eax); // Function. 2443 PushOperand(eax); // Function.
2432 PushOperand(edx); // Receiver. 2444 PushOperand(edx); // Receiver.
2433 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2445 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2434 2446
2435 // If fast case code has been generated, emit code to push the function 2447 // If fast case code has been generated, emit code to push the function
2436 // and receiver and have the slow path jump around this code. 2448 // and receiver and have the slow path jump around this code.
2437 if (done.is_linked()) { 2449 if (done.is_linked()) {
2438 Label call; 2450 Label call;
2439 __ jmp(&call, Label::kNear); 2451 __ jmp(&call, Label::kNear);
2440 __ bind(&done); 2452 __ bind(&done);
2441 // Push function. 2453 // Push function.
2442 __ push(eax); 2454 __ push(eax);
2443 // The receiver is implicitly the global receiver. Indicate this by 2455 // The receiver is implicitly the global receiver. Indicate this by
(...skipping 24 matching lines...) Expand all
2468 } 2480 }
2469 2481
2470 // Push a copy of the function (found below the arguments) and 2482 // Push a copy of the function (found below the arguments) and
2471 // resolve eval. 2483 // resolve eval.
2472 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); 2484 __ push(Operand(esp, (arg_count + 1) * kPointerSize));
2473 EmitResolvePossiblyDirectEval(expr); 2485 EmitResolvePossiblyDirectEval(expr);
2474 2486
2475 // Touch up the stack with the resolved function. 2487 // Touch up the stack with the resolved function.
2476 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2488 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2477 2489
2478 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2490 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2479 2491
2480 SetCallPosition(expr); 2492 SetCallPosition(expr);
2481 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2493 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2482 __ Set(eax, arg_count); 2494 __ Set(eax, arg_count);
2483 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2495 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2484 expr->tail_call_mode()), 2496 expr->tail_call_mode()),
2485 RelocInfo::CODE_TARGET); 2497 RelocInfo::CODE_TARGET);
2486 OperandStackDepthDecrement(arg_count + 1); 2498 OperandStackDepthDecrement(arg_count + 1);
2487 RecordJSReturnSite(expr); 2499 RecordJSReturnSite(expr);
2488 RestoreContext(); 2500 RestoreContext();
(...skipping 28 matching lines...) Expand all
2517 __ Move(eax, Immediate(arg_count)); 2529 __ Move(eax, Immediate(arg_count));
2518 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2530 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2519 2531
2520 // Record call targets in unoptimized code. 2532 // Record call targets in unoptimized code.
2521 __ EmitLoadTypeFeedbackVector(ebx); 2533 __ EmitLoadTypeFeedbackVector(ebx);
2522 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2534 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot())));
2523 2535
2524 CallConstructStub stub(isolate()); 2536 CallConstructStub stub(isolate());
2525 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); 2537 __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
2526 OperandStackDepthDecrement(arg_count + 1); 2538 OperandStackDepthDecrement(arg_count + 1);
2527 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2539 PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER);
2528 RestoreContext(); 2540 RestoreContext();
2529 context()->Plug(eax); 2541 context()->Plug(eax);
2530 } 2542 }
2531 2543
2532 2544
2533 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2545 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2534 SuperCallReference* super_call_ref = 2546 SuperCallReference* super_call_ref =
2535 expr->expression()->AsSuperCallReference(); 2547 expr->expression()->AsSuperCallReference();
2536 DCHECK_NOT_NULL(super_call_ref); 2548 DCHECK_NOT_NULL(super_call_ref);
2537 2549
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
2953 } 2965 }
2954 2966
2955 2967
2956 void FullCodeGenerator::EmitCall(CallRuntime* expr) { 2968 void FullCodeGenerator::EmitCall(CallRuntime* expr) {
2957 ZoneList<Expression*>* args = expr->arguments(); 2969 ZoneList<Expression*>* args = expr->arguments();
2958 DCHECK_LE(2, args->length()); 2970 DCHECK_LE(2, args->length());
2959 // Push target, receiver and arguments onto the stack. 2971 // Push target, receiver and arguments onto the stack.
2960 for (Expression* const arg : *args) { 2972 for (Expression* const arg : *args) {
2961 VisitForStackValue(arg); 2973 VisitForStackValue(arg);
2962 } 2974 }
2963 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2975 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
2964 // Move target to edi. 2976 // Move target to edi.
2965 int const argc = args->length() - 2; 2977 int const argc = args->length() - 2;
2966 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize)); 2978 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
2967 // Call the target. 2979 // Call the target.
2968 __ mov(eax, Immediate(argc)); 2980 __ mov(eax, Immediate(argc));
2969 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 2981 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2970 OperandStackDepthDecrement(argc + 1); 2982 OperandStackDepthDecrement(argc + 1);
2971 RestoreContext(); 2983 RestoreContext();
2972 // Discard the function left on TOS. 2984 // Discard the function left on TOS.
2973 context()->DropAndPlug(1, eax); 2985 context()->DropAndPlug(1, eax);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
3160 // because we need to prepare a pair of extra administrative AST ids 3172 // because we need to prepare a pair of extra administrative AST ids
3161 // for the optimizing compiler. 3173 // for the optimizing compiler.
3162 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3174 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3163 Label materialize_true, materialize_false, done; 3175 Label materialize_true, materialize_false, done;
3164 VisitForControl(expr->expression(), 3176 VisitForControl(expr->expression(),
3165 &materialize_false, 3177 &materialize_false,
3166 &materialize_true, 3178 &materialize_true,
3167 &materialize_true); 3179 &materialize_true);
3168 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); 3180 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3169 __ bind(&materialize_true); 3181 __ bind(&materialize_true);
3170 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3182 PrepareForBailoutForId(expr->MaterializeTrueId(),
3183 BailoutState::NO_REGISTERS);
3171 if (context()->IsAccumulatorValue()) { 3184 if (context()->IsAccumulatorValue()) {
3172 __ mov(eax, isolate()->factory()->true_value()); 3185 __ mov(eax, isolate()->factory()->true_value());
3173 } else { 3186 } else {
3174 __ Push(isolate()->factory()->true_value()); 3187 __ Push(isolate()->factory()->true_value());
3175 } 3188 }
3176 __ jmp(&done, Label::kNear); 3189 __ jmp(&done, Label::kNear);
3177 __ bind(&materialize_false); 3190 __ bind(&materialize_false);
3178 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3191 PrepareForBailoutForId(expr->MaterializeFalseId(),
3192 BailoutState::NO_REGISTERS);
3179 if (context()->IsAccumulatorValue()) { 3193 if (context()->IsAccumulatorValue()) {
3180 __ mov(eax, isolate()->factory()->false_value()); 3194 __ mov(eax, isolate()->factory()->false_value());
3181 } else { 3195 } else {
3182 __ Push(isolate()->factory()->false_value()); 3196 __ Push(isolate()->factory()->false_value());
3183 } 3197 }
3184 __ bind(&done); 3198 __ bind(&done);
3185 } 3199 }
3186 break; 3200 break;
3187 } 3201 }
3188 3202
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3267 } 3281 }
3268 3282
3269 case VARIABLE: 3283 case VARIABLE:
3270 UNREACHABLE(); 3284 UNREACHABLE();
3271 } 3285 }
3272 } 3286 }
3273 3287
3274 // We need a second deoptimization point after loading the value 3288 // We need a second deoptimization point after loading the value
3275 // in case evaluating the property load my have a side effect. 3289 // in case evaluating the property load my have a side effect.
3276 if (assign_type == VARIABLE) { 3290 if (assign_type == VARIABLE) {
3277 PrepareForBailout(expr->expression(), TOS_REG); 3291 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER);
3278 } else { 3292 } else {
3279 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 3293 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
3280 } 3294 }
3281 3295
3282 // Inline smi case if we are in a loop. 3296 // Inline smi case if we are in a loop.
3283 Label done, stub_call; 3297 Label done, stub_call;
3284 JumpPatchSite patch_site(masm_); 3298 JumpPatchSite patch_site(masm_);
3285 if (ShouldInlineSmiCase(expr->op())) { 3299 if (ShouldInlineSmiCase(expr->op())) {
3286 Label slow; 3300 Label slow;
3287 patch_site.EmitJumpIfNotSmi(eax, &slow, Label::kNear); 3301 patch_site.EmitJumpIfNotSmi(eax, &slow, Label::kNear);
3288 3302
3289 // Save result for postfix expressions. 3303 // Save result for postfix expressions.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3324 } else { 3338 } else {
3325 __ add(eax, Immediate(Smi::FromInt(1))); 3339 __ add(eax, Immediate(Smi::FromInt(1)));
3326 } 3340 }
3327 __ jmp(&stub_call, Label::kNear); 3341 __ jmp(&stub_call, Label::kNear);
3328 __ bind(&slow); 3342 __ bind(&slow);
3329 } 3343 }
3330 3344
3331 // Convert old value into a number. 3345 // Convert old value into a number.
3332 ToNumberStub convert_stub(isolate()); 3346 ToNumberStub convert_stub(isolate());
3333 __ CallStub(&convert_stub); 3347 __ CallStub(&convert_stub);
3334 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); 3348 PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
3335 3349
3336 // Save result for postfix expressions. 3350 // Save result for postfix expressions.
3337 if (expr->is_postfix()) { 3351 if (expr->is_postfix()) {
3338 if (!context()->IsEffect()) { 3352 if (!context()->IsEffect()) {
3339 // Save the result on the stack. If we have a named or keyed property 3353 // Save the result on the stack. If we have a named or keyed property
3340 // we store the result under the receiver that is currently on top 3354 // we store the result under the receiver that is currently on top
3341 // of the stack. 3355 // of the stack.
3342 switch (assign_type) { 3356 switch (assign_type) {
3343 case VARIABLE: 3357 case VARIABLE:
3344 PushOperand(eax); 3358 PushOperand(eax);
(...skipping 27 matching lines...) Expand all
3372 __ bind(&done); 3386 __ bind(&done);
3373 3387
3374 // Store the value returned in eax. 3388 // Store the value returned in eax.
3375 switch (assign_type) { 3389 switch (assign_type) {
3376 case VARIABLE: 3390 case VARIABLE:
3377 if (expr->is_postfix()) { 3391 if (expr->is_postfix()) {
3378 // Perform the assignment as if via '='. 3392 // Perform the assignment as if via '='.
3379 { EffectContext context(this); 3393 { EffectContext context(this);
3380 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3394 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3381 Token::ASSIGN, expr->CountSlot()); 3395 Token::ASSIGN, expr->CountSlot());
3382 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3396 PrepareForBailoutForId(expr->AssignmentId(),
3397 BailoutState::TOS_REGISTER);
3383 context.Plug(eax); 3398 context.Plug(eax);
3384 } 3399 }
3385 // For all contexts except EffectContext We have the result on 3400 // For all contexts except EffectContext We have the result on
3386 // top of the stack. 3401 // top of the stack.
3387 if (!context()->IsEffect()) { 3402 if (!context()->IsEffect()) {
3388 context()->PlugTOS(); 3403 context()->PlugTOS();
3389 } 3404 }
3390 } else { 3405 } else {
3391 // Perform the assignment as if via '='. 3406 // Perform the assignment as if via '='.
3392 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3407 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3393 Token::ASSIGN, expr->CountSlot()); 3408 Token::ASSIGN, expr->CountSlot());
3394 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3409 PrepareForBailoutForId(expr->AssignmentId(),
3410 BailoutState::TOS_REGISTER);
3395 context()->Plug(eax); 3411 context()->Plug(eax);
3396 } 3412 }
3397 break; 3413 break;
3398 case NAMED_PROPERTY: { 3414 case NAMED_PROPERTY: {
3399 __ mov(StoreDescriptor::NameRegister(), 3415 __ mov(StoreDescriptor::NameRegister(),
3400 prop->key()->AsLiteral()->value()); 3416 prop->key()->AsLiteral()->value());
3401 PopOperand(StoreDescriptor::ReceiverRegister()); 3417 PopOperand(StoreDescriptor::ReceiverRegister());
3402 EmitLoadStoreICSlot(expr->CountSlot()); 3418 EmitLoadStoreICSlot(expr->CountSlot());
3403 CallStoreIC(); 3419 CallStoreIC();
3404 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3420 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3405 if (expr->is_postfix()) { 3421 if (expr->is_postfix()) {
3406 if (!context()->IsEffect()) { 3422 if (!context()->IsEffect()) {
3407 context()->PlugTOS(); 3423 context()->PlugTOS();
3408 } 3424 }
3409 } else { 3425 } else {
3410 context()->Plug(eax); 3426 context()->Plug(eax);
3411 } 3427 }
3412 break; 3428 break;
3413 } 3429 }
3414 case NAMED_SUPER_PROPERTY: { 3430 case NAMED_SUPER_PROPERTY: {
(...skipping 18 matching lines...) Expand all
3433 } 3449 }
3434 break; 3450 break;
3435 } 3451 }
3436 case KEYED_PROPERTY: { 3452 case KEYED_PROPERTY: {
3437 PopOperand(StoreDescriptor::NameRegister()); 3453 PopOperand(StoreDescriptor::NameRegister());
3438 PopOperand(StoreDescriptor::ReceiverRegister()); 3454 PopOperand(StoreDescriptor::ReceiverRegister());
3439 Handle<Code> ic = 3455 Handle<Code> ic =
3440 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3456 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3441 EmitLoadStoreICSlot(expr->CountSlot()); 3457 EmitLoadStoreICSlot(expr->CountSlot());
3442 CallIC(ic); 3458 CallIC(ic);
3443 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3459 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3444 if (expr->is_postfix()) { 3460 if (expr->is_postfix()) {
3445 // Result is on the stack 3461 // Result is on the stack
3446 if (!context()->IsEffect()) { 3462 if (!context()->IsEffect()) {
3447 context()->PlugTOS(); 3463 context()->PlugTOS();
3448 } 3464 }
3449 } else { 3465 } else {
3450 context()->Plug(eax); 3466 context()->Plug(eax);
3451 } 3467 }
3452 break; 3468 break;
3453 } 3469 }
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
3815 isolate->builtins()->OnStackReplacement()->entry(), 3831 isolate->builtins()->OnStackReplacement()->entry(),
3816 Assembler::target_address_at(call_target_address, unoptimized_code)); 3832 Assembler::target_address_at(call_target_address, unoptimized_code));
3817 return ON_STACK_REPLACEMENT; 3833 return ON_STACK_REPLACEMENT;
3818 } 3834 }
3819 3835
3820 3836
3821 } // namespace internal 3837 } // namespace internal
3822 } // namespace v8 3838 } // namespace v8
3823 3839
3824 #endif // V8_TARGET_ARCH_X87 3840 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | src/x87/builtins-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698