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

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

Issue 1989983002: PPC/S390: [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry tr… (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/ppc/full-codegen-ppc.cc ('k') | src/ppc/builtins-ppc.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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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_S390 5 #if V8_TARGET_ARCH_S390
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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 // Possibly allocate a local context. 180 // Possibly allocate a local context.
181 if (info->scope()->num_heap_slots() > 0) { 181 if (info->scope()->num_heap_slots() > 0) {
182 // Argument to NewContext is the function, which is still in r3. 182 // Argument to NewContext is the function, which is still in r3.
183 Comment cmnt(masm_, "[ Allocate context"); 183 Comment cmnt(masm_, "[ Allocate context");
184 bool need_write_barrier = true; 184 bool need_write_barrier = true;
185 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 185 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
186 if (info->scope()->is_script_scope()) { 186 if (info->scope()->is_script_scope()) {
187 __ push(r3); 187 __ push(r3);
188 __ Push(info->scope()->GetScopeInfo(info->isolate())); 188 __ Push(info->scope()->GetScopeInfo(info->isolate()));
189 __ CallRuntime(Runtime::kNewScriptContext); 189 __ CallRuntime(Runtime::kNewScriptContext);
190 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 190 PrepareForBailoutForId(BailoutId::ScriptContext(),
191 BailoutState::TOS_REGISTER);
191 // The new target value is not used, clobbering is safe. 192 // The new target value is not used, clobbering is safe.
192 DCHECK_NULL(info->scope()->new_target_var()); 193 DCHECK_NULL(info->scope()->new_target_var());
193 } else { 194 } else {
194 if (info->scope()->new_target_var() != nullptr) { 195 if (info->scope()->new_target_var() != nullptr) {
195 __ push(r5); // Preserve new target. 196 __ push(r5); // Preserve new target.
196 } 197 }
197 if (slots <= FastNewContextStub::kMaximumSlots) { 198 if (slots <= FastNewContextStub::kMaximumSlots) {
198 FastNewContextStub stub(isolate(), slots); 199 FastNewContextStub stub(isolate(), slots);
199 __ CallStub(&stub); 200 __ CallStub(&stub);
200 // Result of FastNewContextStub is always in new space. 201 // Result of FastNewContextStub is always in new space.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 __ Abort(kExpectedNewSpaceObject); 237 __ Abort(kExpectedNewSpaceObject);
237 __ bind(&done); 238 __ bind(&done);
238 } 239 }
239 } 240 }
240 } 241 }
241 } 242 }
242 243
243 // Register holding this function and new target are both trashed in case we 244 // Register holding this function and new target are both trashed in case we
244 // bailout here. But since that can happen only when new target is not used 245 // bailout here. But since that can happen only when new target is not used
245 // and we allocate a context, the value of |function_in_register| is correct. 246 // and we allocate a context, the value of |function_in_register| is correct.
246 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); 247 PrepareForBailoutForId(BailoutId::FunctionContext(),
248 BailoutState::NO_REGISTERS);
247 249
248 // Possibly set up a local binding to the this function which is used in 250 // Possibly set up a local binding to the this function which is used in
249 // derived constructors with super calls. 251 // derived constructors with super calls.
250 Variable* this_function_var = scope()->this_function_var(); 252 Variable* this_function_var = scope()->this_function_var();
251 if (this_function_var != nullptr) { 253 if (this_function_var != nullptr) {
252 Comment cmnt(masm_, "[ This function"); 254 Comment cmnt(masm_, "[ This function");
253 if (!function_in_register_r3) { 255 if (!function_in_register_r3) {
254 __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 256 __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
255 // The write barrier clobbers register again, keep it marked as such. 257 // The write barrier clobbers register again, keep it marked as such.
256 } 258 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 } 302 }
301 303
302 SetVar(arguments, r2, r3, r4); 304 SetVar(arguments, r2, r3, r4);
303 } 305 }
304 306
305 if (FLAG_trace) { 307 if (FLAG_trace) {
306 __ CallRuntime(Runtime::kTraceEnter); 308 __ CallRuntime(Runtime::kTraceEnter);
307 } 309 }
308 310
309 // Visit the declarations and body. 311 // Visit the declarations and body.
310 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 312 PrepareForBailoutForId(BailoutId::FunctionEntry(),
313 BailoutState::NO_REGISTERS);
311 { 314 {
312 Comment cmnt(masm_, "[ Declarations"); 315 Comment cmnt(masm_, "[ Declarations");
313 VisitDeclarations(scope()->declarations()); 316 VisitDeclarations(scope()->declarations());
314 } 317 }
315 318
316 // Assert that the declarations do not use ICs. Otherwise the debugger 319 // Assert that the declarations do not use ICs. Otherwise the debugger
317 // won't be able to redirect a PC at an IC to the correct IC in newly 320 // won't be able to redirect a PC at an IC to the correct IC in newly
318 // recompiled code. 321 // recompiled code.
319 DCHECK_EQ(0, ic_total_count_); 322 DCHECK_EQ(0, ic_total_count_);
320 323
321 { 324 {
322 Comment cmnt(masm_, "[ Stack check"); 325 Comment cmnt(masm_, "[ Stack check");
323 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 326 PrepareForBailoutForId(BailoutId::Declarations(),
327 BailoutState::NO_REGISTERS);
324 Label ok; 328 Label ok;
325 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 329 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
326 __ CmpLogicalP(sp, ip); 330 __ CmpLogicalP(sp, ip);
327 __ bge(&ok, Label::kNear); 331 __ bge(&ok, Label::kNear);
328 __ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET); 332 __ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
329 __ bind(&ok); 333 __ bind(&ok);
330 } 334 }
331 335
332 { 336 {
333 Comment cmnt(masm_, "[ Body"); 337 Comment cmnt(masm_, "[ Body");
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); 389 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
386 390
387 // Record a mapping of this PC offset to the OSR id. This is used to find 391 // Record a mapping of this PC offset to the OSR id. This is used to find
388 // the AST id from the unoptimized code in order to use it as a key into 392 // the AST id from the unoptimized code in order to use it as a key into
389 // the deoptimization input data found in the optimized code. 393 // the deoptimization input data found in the optimized code.
390 RecordBackEdge(stmt->OsrEntryId()); 394 RecordBackEdge(stmt->OsrEntryId());
391 } 395 }
392 EmitProfilingCounterReset(); 396 EmitProfilingCounterReset();
393 397
394 __ bind(&ok); 398 __ bind(&ok);
395 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 399 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
396 // Record a mapping of the OSR id to this PC. This is used if the OSR 400 // Record a mapping of the OSR id to this PC. This is used if the OSR
397 // entry becomes the target of a bailout. We don't expect it to be, but 401 // entry becomes the target of a bailout. We don't expect it to be, but
398 // we want it to work if it is. 402 // we want it to work if it is.
399 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); 403 PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS);
400 } 404 }
401 405
402 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( 406 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
403 bool is_tail_call) { 407 bool is_tail_call) {
404 // Pretend that the exit is a backwards jump to the entry. 408 // Pretend that the exit is a backwards jump to the entry.
405 int weight = 1; 409 int weight = 1;
406 if (info_->ShouldSelfOptimize()) { 410 if (info_->ShouldSelfOptimize()) {
407 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 411 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
408 } else { 412 } else {
409 int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2; 413 int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 bool should_normalize, 671 bool should_normalize,
668 Label* if_true, 672 Label* if_true,
669 Label* if_false) { 673 Label* if_false) {
670 // Only prepare for bailouts before splits if we're in a test 674 // Only prepare for bailouts before splits if we're in a test
671 // context. Otherwise, we let the Visit function deal with the 675 // context. Otherwise, we let the Visit function deal with the
672 // preparation to avoid preparing with the same AST id twice. 676 // preparation to avoid preparing with the same AST id twice.
673 if (!context()->IsTest()) return; 677 if (!context()->IsTest()) return;
674 678
675 Label skip; 679 Label skip;
676 if (should_normalize) __ b(&skip); 680 if (should_normalize) __ b(&skip);
677 PrepareForBailout(expr, TOS_REG); 681 PrepareForBailout(expr, BailoutState::TOS_REGISTER);
678 if (should_normalize) { 682 if (should_normalize) {
679 __ CompareRoot(r2, Heap::kTrueValueRootIndex); 683 __ CompareRoot(r2, Heap::kTrueValueRootIndex);
680 Split(eq, if_true, if_false, NULL); 684 Split(eq, if_true, if_false, NULL);
681 __ bind(&skip); 685 __ bind(&skip);
682 } 686 }
683 } 687 }
684 688
685 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 689 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
686 // The variable in the declaration always resides in the current function 690 // The variable in the declaration always resides in the current function
687 // context. 691 // context.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 } 726 }
723 break; 727 break;
724 728
725 case VariableLocation::CONTEXT: 729 case VariableLocation::CONTEXT:
726 if (hole_init) { 730 if (hole_init) {
727 Comment cmnt(masm_, "[ VariableDeclaration"); 731 Comment cmnt(masm_, "[ VariableDeclaration");
728 EmitDebugCheckDeclarationContext(variable); 732 EmitDebugCheckDeclarationContext(variable);
729 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 733 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
730 __ StoreP(ip, ContextMemOperand(cp, variable->index())); 734 __ StoreP(ip, ContextMemOperand(cp, variable->index()));
731 // No write barrier since the_hole_value is in old space. 735 // No write barrier since the_hole_value is in old space.
732 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 736 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
733 } 737 }
734 break; 738 break;
735 739
736 case VariableLocation::LOOKUP: { 740 case VariableLocation::LOOKUP: {
737 Comment cmnt(masm_, "[ VariableDeclaration"); 741 Comment cmnt(masm_, "[ VariableDeclaration");
738 __ mov(r4, Operand(variable->name())); 742 __ mov(r4, Operand(variable->name()));
739 // Declaration nodes are always introduced in one of four modes. 743 // Declaration nodes are always introduced in one of four modes.
740 DCHECK(IsDeclaredVariableMode(mode)); 744 DCHECK(IsDeclaredVariableMode(mode));
741 // Push initial value, if any. 745 // Push initial value, if any.
742 // Note: For variables we must not push an initial value (such as 746 // Note: For variables we must not push an initial value (such as
743 // 'undefined') because we may have a (legal) redeclaration and we 747 // 'undefined') because we may have a (legal) redeclaration and we
744 // must not destroy the current value. 748 // must not destroy the current value.
745 if (hole_init) { 749 if (hole_init) {
746 __ LoadRoot(r2, Heap::kTheHoleValueRootIndex); 750 __ LoadRoot(r2, Heap::kTheHoleValueRootIndex);
747 } else { 751 } else {
748 __ LoadSmiLiteral(r2, Smi::FromInt(0)); // Indicates no initial value. 752 __ LoadSmiLiteral(r2, Smi::FromInt(0)); // Indicates no initial value.
749 } 753 }
750 __ Push(r4, r2); 754 __ Push(r4, r2);
751 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 755 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
752 __ CallRuntime(Runtime::kDeclareLookupSlot); 756 __ CallRuntime(Runtime::kDeclareLookupSlot);
753 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 757 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
754 break; 758 break;
755 } 759 }
756 } 760 }
757 } 761 }
758 762
759 void FullCodeGenerator::VisitFunctionDeclaration( 763 void FullCodeGenerator::VisitFunctionDeclaration(
760 FunctionDeclaration* declaration) { 764 FunctionDeclaration* declaration) {
761 VariableProxy* proxy = declaration->proxy(); 765 VariableProxy* proxy = declaration->proxy();
762 Variable* variable = proxy->var(); 766 Variable* variable = proxy->var();
763 switch (variable->location()) { 767 switch (variable->location()) {
(...skipping 19 matching lines...) Expand all
783 case VariableLocation::CONTEXT: { 787 case VariableLocation::CONTEXT: {
784 Comment cmnt(masm_, "[ FunctionDeclaration"); 788 Comment cmnt(masm_, "[ FunctionDeclaration");
785 EmitDebugCheckDeclarationContext(variable); 789 EmitDebugCheckDeclarationContext(variable);
786 VisitForAccumulatorValue(declaration->fun()); 790 VisitForAccumulatorValue(declaration->fun());
787 __ StoreP(result_register(), ContextMemOperand(cp, variable->index())); 791 __ StoreP(result_register(), ContextMemOperand(cp, variable->index()));
788 int offset = Context::SlotOffset(variable->index()); 792 int offset = Context::SlotOffset(variable->index());
789 // We know that we have written a function, which is not a smi. 793 // We know that we have written a function, which is not a smi.
790 __ RecordWriteContextSlot(cp, offset, result_register(), r4, 794 __ RecordWriteContextSlot(cp, offset, result_register(), r4,
791 kLRHasBeenSaved, kDontSaveFPRegs, 795 kLRHasBeenSaved, kDontSaveFPRegs,
792 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 796 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
793 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 797 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
794 break; 798 break;
795 } 799 }
796 800
797 case VariableLocation::LOOKUP: { 801 case VariableLocation::LOOKUP: {
798 Comment cmnt(masm_, "[ FunctionDeclaration"); 802 Comment cmnt(masm_, "[ FunctionDeclaration");
799 __ mov(r4, Operand(variable->name())); 803 __ mov(r4, Operand(variable->name()));
800 PushOperand(r4); 804 PushOperand(r4);
801 // Push initial value for function declaration. 805 // Push initial value for function declaration.
802 VisitForStackValue(declaration->fun()); 806 VisitForStackValue(declaration->fun());
803 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); 807 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
804 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); 808 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
805 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 809 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
806 break; 810 break;
807 } 811 }
808 } 812 }
809 } 813 }
810 814
811 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 815 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
812 // Call the runtime to declare the globals. 816 // Call the runtime to declare the globals.
813 __ mov(r3, Operand(pairs)); 817 __ mov(r3, Operand(pairs));
814 __ LoadSmiLiteral(r2, Smi::FromInt(DeclareGlobalsFlags())); 818 __ LoadSmiLiteral(r2, Smi::FromInt(DeclareGlobalsFlags()));
815 __ Push(r3, r2); 819 __ Push(r3, r2);
816 __ CallRuntime(Runtime::kDeclareGlobals); 820 __ CallRuntime(Runtime::kDeclareGlobals);
817 // Return value is ignored. 821 // Return value is ignored.
818 } 822 }
819 823
820 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 824 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
821 // Call the runtime to declare the modules. 825 // Call the runtime to declare the modules.
822 __ Push(descriptions); 826 __ Push(descriptions);
823 __ CallRuntime(Runtime::kDeclareModules); 827 __ CallRuntime(Runtime::kDeclareModules);
824 // Return value is ignored. 828 // Return value is ignored.
825 } 829 }
826 830
827 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 831 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
828 Comment cmnt(masm_, "[ SwitchStatement"); 832 Comment cmnt(masm_, "[ SwitchStatement");
829 Breakable nested_statement(this, stmt); 833 Breakable nested_statement(this, stmt);
830 SetStatementPosition(stmt); 834 SetStatementPosition(stmt);
831 835
832 // Keep the switch value on the stack until a case matches. 836 // Keep the switch value on the stack until a case matches.
833 VisitForStackValue(stmt->tag()); 837 VisitForStackValue(stmt->tag());
834 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 838 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
835 839
836 ZoneList<CaseClause*>* clauses = stmt->cases(); 840 ZoneList<CaseClause*>* clauses = stmt->cases();
837 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 841 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
838 842
839 Label next_test; // Recycled for each test. 843 Label next_test; // Recycled for each test.
840 // Compile all the tests with branches to their bodies. 844 // Compile all the tests with branches to their bodies.
841 for (int i = 0; i < clauses->length(); i++) { 845 for (int i = 0; i < clauses->length(); i++) {
842 CaseClause* clause = clauses->at(i); 846 CaseClause* clause = clauses->at(i);
843 clause->body_target()->Unuse(); 847 clause->body_target()->Unuse();
844 848
(...skipping 29 matching lines...) Expand all
874 878
875 // Record position before stub call for type feedback. 879 // Record position before stub call for type feedback.
876 SetExpressionPosition(clause); 880 SetExpressionPosition(clause);
877 Handle<Code> ic = 881 Handle<Code> ic =
878 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); 882 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
879 CallIC(ic, clause->CompareId()); 883 CallIC(ic, clause->CompareId());
880 patch_site.EmitPatchInfo(); 884 patch_site.EmitPatchInfo();
881 885
882 Label skip; 886 Label skip;
883 __ b(&skip); 887 __ b(&skip);
884 PrepareForBailout(clause, TOS_REG); 888 PrepareForBailout(clause, BailoutState::TOS_REGISTER);
885 __ CompareRoot(r2, Heap::kTrueValueRootIndex); 889 __ CompareRoot(r2, Heap::kTrueValueRootIndex);
886 __ bne(&next_test); 890 __ bne(&next_test);
887 __ Drop(1); 891 __ Drop(1);
888 __ b(clause->body_target()); 892 __ b(clause->body_target());
889 __ bind(&skip); 893 __ bind(&skip);
890 894
891 __ CmpP(r2, Operand::Zero()); 895 __ CmpP(r2, Operand::Zero());
892 __ bne(&next_test); 896 __ bne(&next_test);
893 __ Drop(1); // Switch value is no longer needed. 897 __ Drop(1); // Switch value is no longer needed.
894 __ b(clause->body_target()); 898 __ b(clause->body_target());
895 } 899 }
896 900
897 // Discard the test value and jump to the default if present, otherwise to 901 // Discard the test value and jump to the default if present, otherwise to
898 // the end of the statement. 902 // the end of the statement.
899 __ bind(&next_test); 903 __ bind(&next_test);
900 DropOperands(1); // Switch value is no longer needed. 904 DropOperands(1); // Switch value is no longer needed.
901 if (default_clause == NULL) { 905 if (default_clause == NULL) {
902 __ b(nested_statement.break_label()); 906 __ b(nested_statement.break_label());
903 } else { 907 } else {
904 __ b(default_clause->body_target()); 908 __ b(default_clause->body_target());
905 } 909 }
906 910
907 // Compile all the case bodies. 911 // Compile all the case bodies.
908 for (int i = 0; i < clauses->length(); i++) { 912 for (int i = 0; i < clauses->length(); i++) {
909 Comment cmnt(masm_, "[ Case body"); 913 Comment cmnt(masm_, "[ Case body");
910 CaseClause* clause = clauses->at(i); 914 CaseClause* clause = clauses->at(i);
911 __ bind(clause->body_target()); 915 __ bind(clause->body_target());
912 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 916 PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS);
913 VisitStatements(clause->statements()); 917 VisitStatements(clause->statements());
914 } 918 }
915 919
916 __ bind(nested_statement.break_label()); 920 __ bind(nested_statement.break_label());
917 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 921 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
918 } 922 }
919 923
920 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 924 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
921 Comment cmnt(masm_, "[ ForInStatement"); 925 Comment cmnt(masm_, "[ ForInStatement");
922 SetStatementPosition(stmt, SKIP_BREAK); 926 SetStatementPosition(stmt, SKIP_BREAK);
923 927
924 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 928 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
925 929
926 // Get the object to enumerate over. 930 // Get the object to enumerate over.
927 SetExpressionAsStatementPosition(stmt->enumerable()); 931 SetExpressionAsStatementPosition(stmt->enumerable());
(...skipping 11 matching lines...) Expand all
939 __ CompareObjectType(r2, r3, r3, FIRST_JS_RECEIVER_TYPE); 943 __ CompareObjectType(r2, r3, r3, FIRST_JS_RECEIVER_TYPE);
940 __ bge(&done_convert); 944 __ bge(&done_convert);
941 __ CompareRoot(r2, Heap::kNullValueRootIndex); 945 __ CompareRoot(r2, Heap::kNullValueRootIndex);
942 __ beq(&exit); 946 __ beq(&exit);
943 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); 947 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
944 __ beq(&exit); 948 __ beq(&exit);
945 __ bind(&convert); 949 __ bind(&convert);
946 ToObjectStub stub(isolate()); 950 ToObjectStub stub(isolate());
947 __ CallStub(&stub); 951 __ CallStub(&stub);
948 __ bind(&done_convert); 952 __ bind(&done_convert);
949 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); 953 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
950 __ push(r2); 954 __ push(r2);
951 955
952 // Check cache validity in generated code. If we cannot guarantee cache 956 // Check cache validity in generated code. If we cannot guarantee cache
953 // validity, call the runtime system to check cache validity or get the 957 // validity, call the runtime system to check cache validity or get the
954 // property names in a fixed array. Note: Proxies never have an enum cache, 958 // property names in a fixed array. Note: Proxies never have an enum cache,
955 // so will always take the slow path. 959 // so will always take the slow path.
956 Label call_runtime; 960 Label call_runtime;
957 __ CheckEnumCache(&call_runtime); 961 __ CheckEnumCache(&call_runtime);
958 962
959 // The enum cache is valid. Load the map of the object being 963 // The enum cache is valid. Load the map of the object being
960 // iterated over and use the cache for the iteration. 964 // iterated over and use the cache for the iteration.
961 Label use_cache; 965 Label use_cache;
962 __ LoadP(r2, FieldMemOperand(r2, HeapObject::kMapOffset)); 966 __ LoadP(r2, FieldMemOperand(r2, HeapObject::kMapOffset));
963 __ b(&use_cache); 967 __ b(&use_cache);
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(r2); // Duplicate the enumerable object on the stack. 971 __ push(r2); // Duplicate the enumerable object on the stack.
968 __ CallRuntime(Runtime::kForInEnumerate); 972 __ CallRuntime(Runtime::kForInEnumerate);
969 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 973 PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER);
970 974
971 // If we got a map from the runtime call, we can do a fast 975 // If we got a map from the runtime call, we can do a fast
972 // modification check. Otherwise, we got a fixed array, and we have 976 // modification check. Otherwise, we got a fixed array, and we have
973 // to do a slow check. 977 // to do a slow check.
974 Label fixed_array; 978 Label fixed_array;
975 __ LoadP(r4, FieldMemOperand(r2, HeapObject::kMapOffset)); 979 __ LoadP(r4, FieldMemOperand(r2, HeapObject::kMapOffset));
976 __ CompareRoot(r4, Heap::kMetaMapRootIndex); 980 __ CompareRoot(r4, Heap::kMetaMapRootIndex);
977 __ bne(&fixed_array); 981 __ bne(&fixed_array);
978 982
979 // We got a map in register r2. Get the enumeration cache from it. 983 // We got a map in register r2. Get the enumeration cache from it.
(...skipping 20 matching lines...) Expand all
1000 __ Drop(1); 1004 __ Drop(1);
1001 __ b(&exit); 1005 __ b(&exit);
1002 1006
1003 // We got a fixed array in register r2. Iterate through that. 1007 // We got a fixed array in register r2. Iterate through that.
1004 __ bind(&fixed_array); 1008 __ bind(&fixed_array);
1005 1009
1006 __ LoadSmiLiteral(r3, Smi::FromInt(1)); // Smi(1) indicates slow check 1010 __ LoadSmiLiteral(r3, Smi::FromInt(1)); // Smi(1) indicates slow check
1007 __ Push(r3, r2); // Smi and array 1011 __ Push(r3, r2); // Smi and array
1008 __ LoadP(r3, FieldMemOperand(r2, FixedArray::kLengthOffset)); 1012 __ LoadP(r3, FieldMemOperand(r2, FixedArray::kLengthOffset));
1009 __ Push(r3); // Fixed array length (as smi). 1013 __ Push(r3); // Fixed array length (as smi).
1010 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); 1014 PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS);
1011 __ LoadSmiLiteral(r2, Smi::FromInt(0)); 1015 __ LoadSmiLiteral(r2, Smi::FromInt(0));
1012 __ Push(r2); // Initial index. 1016 __ Push(r2); // Initial index.
1013 1017
1014 // Generate code for doing the condition check. 1018 // Generate code for doing the condition check.
1015 __ bind(&loop); 1019 __ bind(&loop);
1016 SetExpressionAsStatementPosition(stmt->each()); 1020 SetExpressionAsStatementPosition(stmt->each());
1017 1021
1018 // Load the current count to r2, load the length to r3. 1022 // Load the current count to r2, load the length to r3.
1019 __ LoadP(r2, MemOperand(sp, 0 * kPointerSize)); 1023 __ LoadP(r2, MemOperand(sp, 0 * kPointerSize));
1020 __ LoadP(r3, MemOperand(sp, 1 * kPointerSize)); 1024 __ LoadP(r3, MemOperand(sp, 1 * kPointerSize));
(...skipping 23 matching lines...) Expand all
1044 __ EmitLoadTypeFeedbackVector(r2); 1048 __ EmitLoadTypeFeedbackVector(r2);
1045 __ mov(r4, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 1049 __ mov(r4, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1046 __ StoreP( 1050 __ StoreP(
1047 r4, FieldMemOperand(r2, FixedArray::OffsetOfElementAt(vector_index)), r0); 1051 r4, FieldMemOperand(r2, FixedArray::OffsetOfElementAt(vector_index)), r0);
1048 1052
1049 // Convert the entry to a string or (smi) 0 if it isn't a property 1053 // Convert the entry to a string or (smi) 0 if it isn't a property
1050 // any more. If the property has been removed while iterating, we 1054 // any more. If the property has been removed while iterating, we
1051 // just skip it. 1055 // just skip it.
1052 __ Push(r3, r5); // Enumerable and current entry. 1056 __ Push(r3, r5); // Enumerable and current entry.
1053 __ CallRuntime(Runtime::kForInFilter); 1057 __ CallRuntime(Runtime::kForInFilter);
1054 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1058 PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
1055 __ LoadRR(r5, r2); 1059 __ LoadRR(r5, r2);
1056 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 1060 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
1057 __ CmpP(r2, r0); 1061 __ CmpP(r2, r0);
1058 __ beq(loop_statement.continue_label()); 1062 __ beq(loop_statement.continue_label());
1059 1063
1060 // Update the 'each' property or variable from the possibly filtered 1064 // Update the 'each' property or variable from the possibly filtered
1061 // entry in register r5. 1065 // entry in register r5.
1062 __ bind(&update_each); 1066 __ bind(&update_each);
1063 __ LoadRR(result_register(), r5); 1067 __ LoadRR(result_register(), r5);
1064 // Perform the assignment as if via '='. 1068 // Perform the assignment as if via '='.
1065 { 1069 {
1066 EffectContext context(this); 1070 EffectContext context(this);
1067 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1071 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1068 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); 1072 PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS);
1069 } 1073 }
1070 1074
1071 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). 1075 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
1072 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1076 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
1073 // Generate code for the body of the loop. 1077 // Generate code for the body of the loop.
1074 Visit(stmt->body()); 1078 Visit(stmt->body());
1075 1079
1076 // Generate code for the going to the next element by incrementing 1080 // Generate code for the going to the next element by incrementing
1077 // the index (smi) stored on top of the stack. 1081 // the index (smi) stored on top of the stack.
1078 __ bind(loop_statement.continue_label()); 1082 __ bind(loop_statement.continue_label());
1079 __ pop(r2); 1083 __ pop(r2);
1080 __ AddSmiLiteral(r2, r2, Smi::FromInt(1), r0); 1084 __ AddSmiLiteral(r2, r2, Smi::FromInt(1), r0);
1081 __ push(r2); 1085 __ push(r2);
1082 1086
1083 EmitBackEdgeBookkeeping(stmt, &loop); 1087 EmitBackEdgeBookkeeping(stmt, &loop);
1084 __ b(&loop); 1088 __ b(&loop);
1085 1089
1086 // Remove the pointers stored on the stack. 1090 // Remove the pointers stored on the stack.
1087 __ bind(loop_statement.break_label()); 1091 __ bind(loop_statement.break_label());
1088 DropOperands(5); 1092 DropOperands(5);
1089 1093
1090 // Exit and decrement the loop depth. 1094 // Exit and decrement the loop depth.
1091 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1095 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
1092 __ bind(&exit); 1096 __ bind(&exit);
1093 decrement_loop_depth(); 1097 decrement_loop_depth();
1094 } 1098 }
1095 1099
1096 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1100 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1097 FeedbackVectorSlot slot) { 1101 FeedbackVectorSlot slot) {
1098 DCHECK(NeedsHomeObject(initializer)); 1102 DCHECK(NeedsHomeObject(initializer));
1099 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1103 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1100 __ mov(StoreDescriptor::NameRegister(), 1104 __ mov(StoreDescriptor::NameRegister(),
1101 Operand(isolate()->factory()->home_object_symbol())); 1105 Operand(isolate()->factory()->home_object_symbol()));
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); 1236 __ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
1233 __ mov(LoadDescriptor::SlotRegister(), 1237 __ mov(LoadDescriptor::SlotRegister(),
1234 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); 1238 Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
1235 CallLoadIC(typeof_mode); 1239 CallLoadIC(typeof_mode);
1236 } 1240 }
1237 1241
1238 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1242 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1239 TypeofMode typeof_mode) { 1243 TypeofMode typeof_mode) {
1240 // Record position before possible IC call. 1244 // Record position before possible IC call.
1241 SetExpressionPosition(proxy); 1245 SetExpressionPosition(proxy);
1242 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1246 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1243 Variable* var = proxy->var(); 1247 Variable* var = proxy->var();
1244 1248
1245 // Three cases: global variables, lookup variables, and all other types of 1249 // Three cases: global variables, lookup variables, and all other types of
1246 // variables. 1250 // variables.
1247 switch (var->location()) { 1251 switch (var->location()) {
1248 case VariableLocation::GLOBAL: 1252 case VariableLocation::GLOBAL:
1249 case VariableLocation::UNALLOCATED: { 1253 case VariableLocation::UNALLOCATED: {
1250 Comment cmnt(masm_, "[ Global variable"); 1254 Comment cmnt(masm_, "[ Global variable");
1251 EmitGlobalVariableLoad(proxy, typeof_mode); 1255 EmitGlobalVariableLoad(proxy, typeof_mode);
1252 context()->Plug(r2); 1256 context()->Plug(r2);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 int flags = expr->ComputeFlags(); 1340 int flags = expr->ComputeFlags();
1337 __ LoadSmiLiteral(r2, Smi::FromInt(flags)); 1341 __ LoadSmiLiteral(r2, Smi::FromInt(flags));
1338 if (MustCreateObjectLiteralWithRuntime(expr)) { 1342 if (MustCreateObjectLiteralWithRuntime(expr)) {
1339 __ Push(r5, r4, r3, r2); 1343 __ Push(r5, r4, r3, r2);
1340 __ CallRuntime(Runtime::kCreateObjectLiteral); 1344 __ CallRuntime(Runtime::kCreateObjectLiteral);
1341 } else { 1345 } else {
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 r2. 1353 // result_saved is false the result is in r2.
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(r2)); 1381 DCHECK(StoreDescriptor::ValueRegister().is(r2));
1378 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); 1382 __ mov(StoreDescriptor::NameRegister(), Operand(key->value()));
1379 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1383 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
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 1387
1384 if (NeedsHomeObject(value)) { 1388 if (NeedsHomeObject(value)) {
1385 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1389 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1386 } 1390 }
1387 } else { 1391 } else {
1388 VisitForEffect(value); 1392 VisitForEffect(value);
1389 } 1393 }
1390 break; 1394 break;
1391 } 1395 }
1392 // Duplicate receiver on stack. 1396 // Duplicate receiver on stack.
(...skipping 13 matching lines...) Expand all
1406 } 1410 }
1407 break; 1411 break;
1408 case ObjectLiteral::Property::PROTOTYPE: 1412 case ObjectLiteral::Property::PROTOTYPE:
1409 // Duplicate receiver on stack. 1413 // Duplicate receiver on stack.
1410 __ LoadP(r2, MemOperand(sp)); 1414 __ LoadP(r2, MemOperand(sp));
1411 PushOperand(r2); 1415 PushOperand(r2);
1412 VisitForStackValue(value); 1416 VisitForStackValue(value);
1413 DCHECK(property->emit_store()); 1417 DCHECK(property->emit_store());
1414 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1418 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1415 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1419 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1416 NO_REGISTERS); 1420 BailoutState::NO_REGISTERS);
1417 break; 1421 break;
1418 case ObjectLiteral::Property::GETTER: 1422 case ObjectLiteral::Property::GETTER:
1419 if (property->emit_store()) { 1423 if (property->emit_store()) {
1420 accessor_table.lookup(key)->second->getter = property; 1424 accessor_table.lookup(key)->second->getter = property;
1421 } 1425 }
1422 break; 1426 break;
1423 case ObjectLiteral::Property::SETTER: 1427 case ObjectLiteral::Property::SETTER:
1424 if (property->emit_store()) { 1428 if (property->emit_store()) {
1425 accessor_table.lookup(key)->second->setter = property; 1429 accessor_table.lookup(key)->second->setter = property;
1426 } 1430 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 1466
1463 __ LoadP(r2, MemOperand(sp)); // Duplicate receiver. 1467 __ LoadP(r2, MemOperand(sp)); // Duplicate receiver.
1464 PushOperand(r2); 1468 PushOperand(r2);
1465 1469
1466 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1470 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1467 DCHECK(!property->is_computed_name()); 1471 DCHECK(!property->is_computed_name());
1468 VisitForStackValue(value); 1472 VisitForStackValue(value);
1469 DCHECK(property->emit_store()); 1473 DCHECK(property->emit_store());
1470 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1474 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1471 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1475 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1472 NO_REGISTERS); 1476 BailoutState::NO_REGISTERS);
1473 } else { 1477 } else {
1474 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1478 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1475 VisitForStackValue(value); 1479 VisitForStackValue(value);
1476 if (NeedsHomeObject(value)) { 1480 if (NeedsHomeObject(value)) {
1477 EmitSetHomeObject(value, 2, property->GetSlot()); 1481 EmitSetHomeObject(value, 2, property->GetSlot());
1478 } 1482 }
1479 1483
1480 switch (property->kind()) { 1484 switch (property->kind()) {
1481 case ObjectLiteral::Property::CONSTANT: 1485 case ObjectLiteral::Property::CONSTANT:
1482 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1486 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1534 __ LoadSmiLiteral(r4, Smi::FromInt(expr->literal_index())); 1538 __ LoadSmiLiteral(r4, Smi::FromInt(expr->literal_index()));
1535 __ mov(r3, Operand(constant_elements)); 1539 __ mov(r3, Operand(constant_elements));
1536 if (MustCreateArrayLiteralWithRuntime(expr)) { 1540 if (MustCreateArrayLiteralWithRuntime(expr)) {
1537 __ LoadSmiLiteral(r2, Smi::FromInt(expr->ComputeFlags())); 1541 __ LoadSmiLiteral(r2, Smi::FromInt(expr->ComputeFlags()));
1538 __ Push(r5, r4, r3, r2); 1542 __ Push(r5, r4, r3, r2);
1539 __ CallRuntime(Runtime::kCreateArrayLiteral); 1543 __ CallRuntime(Runtime::kCreateArrayLiteral);
1540 } else { 1544 } else {
1541 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1545 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1542 __ CallStub(&stub); 1546 __ CallStub(&stub);
1543 } 1547 }
1544 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1548 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
1545 1549
1546 bool result_saved = false; // Is the result saved to the stack? 1550 bool result_saved = false; // Is the result saved to the stack?
1547 ZoneList<Expression*>* subexprs = expr->values(); 1551 ZoneList<Expression*>* subexprs = expr->values();
1548 int length = subexprs->length(); 1552 int length = subexprs->length();
1549 1553
1550 // Emit code to evaluate all the non-constant subexpressions and to store 1554 // Emit code to evaluate all the non-constant subexpressions and to store
1551 // them into the newly cloned array. 1555 // them into the newly cloned array.
1552 int array_index = 0; 1556 int array_index = 0;
1553 for (; array_index < length; array_index++) { 1557 for (; array_index < length; array_index++) {
1554 Expression* subexpr = subexprs->at(array_index); 1558 Expression* subexpr = subexprs->at(array_index);
1555 DCHECK(!subexpr->IsSpread()); 1559 DCHECK(!subexpr->IsSpread());
1556 // If the subexpression is a literal or a simple materialized literal it 1560 // If the subexpression is a literal or a simple materialized literal it
1557 // is already set in the cloned array. 1561 // is already set in the cloned array.
1558 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1562 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1559 1563
1560 if (!result_saved) { 1564 if (!result_saved) {
1561 PushOperand(r2); 1565 PushOperand(r2);
1562 result_saved = true; 1566 result_saved = true;
1563 } 1567 }
1564 VisitForAccumulatorValue(subexpr); 1568 VisitForAccumulatorValue(subexpr);
1565 1569
1566 __ LoadSmiLiteral(StoreDescriptor::NameRegister(), 1570 __ LoadSmiLiteral(StoreDescriptor::NameRegister(),
1567 Smi::FromInt(array_index)); 1571 Smi::FromInt(array_index));
1568 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1572 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1569 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1573 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1570 Handle<Code> ic = 1574 Handle<Code> ic =
1571 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1575 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1572 CallIC(ic); 1576 CallIC(ic);
1573 1577
1574 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1578 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1579 BailoutState::NO_REGISTERS);
1575 } 1580 }
1576 1581
1577 // In case the array literal contains spread expressions it has two parts. The 1582 // In case the array literal contains spread expressions it has two parts. The
1578 // first part is the "static" array which has a literal index is handled 1583 // first part is the "static" array which has a literal index is handled
1579 // above. The second part is the part after the first spread expression 1584 // above. The second part is the part after the first spread expression
1580 // (inclusive) and these elements gets appended to the array. Note that the 1585 // (inclusive) and these elements gets appended to the array. Note that the
1581 // number elements an iterable produces is unknown ahead of time. 1586 // number elements an iterable produces is unknown ahead of time.
1582 if (array_index < length && result_saved) { 1587 if (array_index < length && result_saved) {
1583 PopOperand(r2); 1588 PopOperand(r2);
1584 result_saved = false; 1589 result_saved = false;
1585 } 1590 }
1586 for (; array_index < length; array_index++) { 1591 for (; array_index < length; array_index++) {
1587 Expression* subexpr = subexprs->at(array_index); 1592 Expression* subexpr = subexprs->at(array_index);
1588 1593
1589 PushOperand(r2); 1594 PushOperand(r2);
1590 DCHECK(!subexpr->IsSpread()); 1595 DCHECK(!subexpr->IsSpread());
1591 VisitForStackValue(subexpr); 1596 VisitForStackValue(subexpr);
1592 CallRuntimeWithOperands(Runtime::kAppendElement); 1597 CallRuntimeWithOperands(Runtime::kAppendElement);
1593 1598
1594 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1599 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1600 BailoutState::NO_REGISTERS);
1595 } 1601 }
1596 1602
1597 if (result_saved) { 1603 if (result_saved) {
1598 context()->PlugTOS(); 1604 context()->PlugTOS();
1599 } else { 1605 } else {
1600 context()->Plug(r2); 1606 context()->Plug(r2);
1601 } 1607 }
1602 } 1608 }
1603 1609
1604 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1610 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1666 } 1672 }
1667 1673
1668 // For compound assignments we need another deoptimization point after the 1674 // For compound assignments we need another deoptimization point after the
1669 // variable/property load. 1675 // variable/property load.
1670 if (expr->is_compound()) { 1676 if (expr->is_compound()) {
1671 { 1677 {
1672 AccumulatorValueContext context(this); 1678 AccumulatorValueContext context(this);
1673 switch (assign_type) { 1679 switch (assign_type) {
1674 case VARIABLE: 1680 case VARIABLE:
1675 EmitVariableLoad(expr->target()->AsVariableProxy()); 1681 EmitVariableLoad(expr->target()->AsVariableProxy());
1676 PrepareForBailout(expr->target(), TOS_REG); 1682 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER);
1677 break; 1683 break;
1678 case NAMED_PROPERTY: 1684 case NAMED_PROPERTY:
1679 EmitNamedPropertyLoad(property); 1685 EmitNamedPropertyLoad(property);
1680 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1686 PrepareForBailoutForId(property->LoadId(),
1687 BailoutState::TOS_REGISTER);
1681 break; 1688 break;
1682 case NAMED_SUPER_PROPERTY: 1689 case NAMED_SUPER_PROPERTY:
1683 EmitNamedSuperPropertyLoad(property); 1690 EmitNamedSuperPropertyLoad(property);
1684 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1691 PrepareForBailoutForId(property->LoadId(),
1692 BailoutState::TOS_REGISTER);
1685 break; 1693 break;
1686 case KEYED_SUPER_PROPERTY: 1694 case KEYED_SUPER_PROPERTY:
1687 EmitKeyedSuperPropertyLoad(property); 1695 EmitKeyedSuperPropertyLoad(property);
1688 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1696 PrepareForBailoutForId(property->LoadId(),
1697 BailoutState::TOS_REGISTER);
1689 break; 1698 break;
1690 case KEYED_PROPERTY: 1699 case KEYED_PROPERTY:
1691 EmitKeyedPropertyLoad(property); 1700 EmitKeyedPropertyLoad(property);
1692 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1701 PrepareForBailoutForId(property->LoadId(),
1702 BailoutState::TOS_REGISTER);
1693 break; 1703 break;
1694 } 1704 }
1695 } 1705 }
1696 1706
1697 Token::Value op = expr->binary_op(); 1707 Token::Value op = expr->binary_op();
1698 PushOperand(r2); // Left operand goes on the stack. 1708 PushOperand(r2); // Left operand goes on the stack.
1699 VisitForAccumulatorValue(expr->value()); 1709 VisitForAccumulatorValue(expr->value());
1700 1710
1701 AccumulatorValueContext context(this); 1711 AccumulatorValueContext context(this);
1702 if (ShouldInlineSmiCase(op)) { 1712 if (ShouldInlineSmiCase(op)) {
1703 EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(), 1713 EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(),
1704 expr->value()); 1714 expr->value());
1705 } else { 1715 } else {
1706 EmitBinaryOp(expr->binary_operation(), op); 1716 EmitBinaryOp(expr->binary_operation(), op);
1707 } 1717 }
1708 1718
1709 // Deoptimization point in case the binary operation may have side effects. 1719 // Deoptimization point in case the binary operation may have side effects.
1710 PrepareForBailout(expr->binary_operation(), TOS_REG); 1720 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER);
1711 } else { 1721 } else {
1712 VisitForAccumulatorValue(expr->value()); 1722 VisitForAccumulatorValue(expr->value());
1713 } 1723 }
1714 1724
1715 SetExpressionPosition(expr); 1725 SetExpressionPosition(expr);
1716 1726
1717 // Store the value. 1727 // Store the value.
1718 switch (assign_type) { 1728 switch (assign_type) {
1719 case VARIABLE: 1729 case VARIABLE:
1720 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1730 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1721 expr->op(), expr->AssignmentSlot()); 1731 expr->op(), expr->AssignmentSlot());
1722 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1732 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1723 context()->Plug(r2); 1733 context()->Plug(r2);
1724 break; 1734 break;
1725 case NAMED_PROPERTY: 1735 case NAMED_PROPERTY:
1726 EmitNamedPropertyAssignment(expr); 1736 EmitNamedPropertyAssignment(expr);
1727 break; 1737 break;
1728 case NAMED_SUPER_PROPERTY: 1738 case NAMED_SUPER_PROPERTY:
1729 EmitNamedSuperPropertyStore(property); 1739 EmitNamedSuperPropertyStore(property);
1730 context()->Plug(r2); 1740 context()->Plug(r2);
1731 break; 1741 break;
1732 case KEYED_SUPER_PROPERTY: 1742 case KEYED_SUPER_PROPERTY:
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 Property* prop = expr->target()->AsProperty(); 2229 Property* prop = expr->target()->AsProperty();
2220 DCHECK(prop != NULL); 2230 DCHECK(prop != NULL);
2221 DCHECK(prop->key()->IsLiteral()); 2231 DCHECK(prop->key()->IsLiteral());
2222 2232
2223 __ mov(StoreDescriptor::NameRegister(), 2233 __ mov(StoreDescriptor::NameRegister(),
2224 Operand(prop->key()->AsLiteral()->value())); 2234 Operand(prop->key()->AsLiteral()->value()));
2225 PopOperand(StoreDescriptor::ReceiverRegister()); 2235 PopOperand(StoreDescriptor::ReceiverRegister());
2226 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2236 EmitLoadStoreICSlot(expr->AssignmentSlot());
2227 CallStoreIC(); 2237 CallStoreIC();
2228 2238
2229 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2239 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2230 context()->Plug(r2); 2240 context()->Plug(r2);
2231 } 2241 }
2232 2242
2233 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2243 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2234 // Assignment to named property of super. 2244 // Assignment to named property of super.
2235 // r2 : value 2245 // r2 : value
2236 // stack : receiver ('this'), home_object 2246 // stack : receiver ('this'), home_object
2237 DCHECK(prop != NULL); 2247 DCHECK(prop != NULL);
2238 Literal* key = prop->key()->AsLiteral(); 2248 Literal* key = prop->key()->AsLiteral();
2239 DCHECK(key != NULL); 2249 DCHECK(key != NULL);
(...skipping 21 matching lines...) Expand all
2261 // Assignment to a property, using a keyed store IC. 2271 // Assignment to a property, using a keyed store IC.
2262 PopOperands(StoreDescriptor::ReceiverRegister(), 2272 PopOperands(StoreDescriptor::ReceiverRegister(),
2263 StoreDescriptor::NameRegister()); 2273 StoreDescriptor::NameRegister());
2264 DCHECK(StoreDescriptor::ValueRegister().is(r2)); 2274 DCHECK(StoreDescriptor::ValueRegister().is(r2));
2265 2275
2266 Handle<Code> ic = 2276 Handle<Code> ic =
2267 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2277 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2268 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2278 EmitLoadStoreICSlot(expr->AssignmentSlot());
2269 CallIC(ic); 2279 CallIC(ic);
2270 2280
2271 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2281 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2272 context()->Plug(r2); 2282 context()->Plug(r2);
2273 } 2283 }
2274 2284
2275 void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) { 2285 void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) {
2276 ic_total_count_++; 2286 ic_total_count_++;
2277 __ Call(code, RelocInfo::CODE_TARGET, ast_id); 2287 __ Call(code, RelocInfo::CODE_TARGET, ast_id);
2278 } 2288 }
2279 2289
2280 // Code common for calls using the IC. 2290 // Code common for calls using the IC.
2281 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2291 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2282 Expression* callee = expr->expression(); 2292 Expression* callee = expr->expression();
2283 2293
2284 // Get the target function. 2294 // Get the target function.
2285 ConvertReceiverMode convert_mode; 2295 ConvertReceiverMode convert_mode;
2286 if (callee->IsVariableProxy()) { 2296 if (callee->IsVariableProxy()) {
2287 { 2297 {
2288 StackValueContext context(this); 2298 StackValueContext context(this);
2289 EmitVariableLoad(callee->AsVariableProxy()); 2299 EmitVariableLoad(callee->AsVariableProxy());
2290 PrepareForBailout(callee, NO_REGISTERS); 2300 PrepareForBailout(callee, BailoutState::NO_REGISTERS);
2291 } 2301 }
2292 // Push undefined as receiver. This is patched in the method prologue if it 2302 // Push undefined as receiver. This is patched in the method prologue if it
2293 // is a sloppy mode method. 2303 // is a sloppy mode method.
2294 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2304 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2295 PushOperand(r1); 2305 PushOperand(r1);
2296 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2306 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2297 } else { 2307 } else {
2298 // Load the function from the receiver. 2308 // Load the function from the receiver.
2299 DCHECK(callee->IsProperty()); 2309 DCHECK(callee->IsProperty());
2300 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2310 DCHECK(!callee->AsProperty()->IsSuperAccess());
2301 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2311 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2302 EmitNamedPropertyLoad(callee->AsProperty()); 2312 EmitNamedPropertyLoad(callee->AsProperty());
2303 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2313 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2314 BailoutState::TOS_REGISTER);
2304 // Push the target function under the receiver. 2315 // Push the target function under the receiver.
2305 __ LoadP(r1, MemOperand(sp, 0)); 2316 __ LoadP(r1, MemOperand(sp, 0));
2306 PushOperand(r1); 2317 PushOperand(r1);
2307 __ StoreP(r2, MemOperand(sp, kPointerSize)); 2318 __ StoreP(r2, MemOperand(sp, kPointerSize));
2308 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2319 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2309 } 2320 }
2310 2321
2311 EmitCall(expr, convert_mode); 2322 EmitCall(expr, convert_mode);
2312 } 2323 }
2313 2324
(...skipping 15 matching lines...) Expand all
2329 PushOperands(scratch, r2, r2, scratch); 2340 PushOperands(scratch, r2, r2, scratch);
2330 PushOperand(key->value()); 2341 PushOperand(key->value());
2331 2342
2332 // Stack here: 2343 // Stack here:
2333 // - home_object 2344 // - home_object
2334 // - this (receiver) 2345 // - this (receiver)
2335 // - this (receiver) <-- LoadFromSuper will pop here and below. 2346 // - this (receiver) <-- LoadFromSuper will pop here and below.
2336 // - home_object 2347 // - home_object
2337 // - key 2348 // - key
2338 CallRuntimeWithOperands(Runtime::kLoadFromSuper); 2349 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2339 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2350 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2340 2351
2341 // Replace home_object with target function. 2352 // Replace home_object with target function.
2342 __ StoreP(r2, MemOperand(sp, kPointerSize)); 2353 __ StoreP(r2, MemOperand(sp, kPointerSize));
2343 2354
2344 // Stack here: 2355 // Stack here:
2345 // - target function 2356 // - target function
2346 // - this (receiver) 2357 // - this (receiver)
2347 EmitCall(expr); 2358 EmitCall(expr);
2348 } 2359 }
2349 2360
2350 // Code common for calls using the IC. 2361 // Code common for calls using the IC.
2351 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { 2362 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) {
2352 // Load the key. 2363 // Load the key.
2353 VisitForAccumulatorValue(key); 2364 VisitForAccumulatorValue(key);
2354 2365
2355 Expression* callee = expr->expression(); 2366 Expression* callee = expr->expression();
2356 2367
2357 // Load the function from the receiver. 2368 // Load the function from the receiver.
2358 DCHECK(callee->IsProperty()); 2369 DCHECK(callee->IsProperty());
2359 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2370 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2360 __ Move(LoadDescriptor::NameRegister(), r2); 2371 __ Move(LoadDescriptor::NameRegister(), r2);
2361 EmitKeyedPropertyLoad(callee->AsProperty()); 2372 EmitKeyedPropertyLoad(callee->AsProperty());
2362 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2373 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2374 BailoutState::TOS_REGISTER);
2363 2375
2364 // Push the target function under the receiver. 2376 // Push the target function under the receiver.
2365 __ LoadP(ip, MemOperand(sp, 0)); 2377 __ LoadP(ip, MemOperand(sp, 0));
2366 PushOperand(ip); 2378 PushOperand(ip);
2367 __ StoreP(r2, MemOperand(sp, kPointerSize)); 2379 __ StoreP(r2, MemOperand(sp, kPointerSize));
2368 2380
2369 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2381 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2370 } 2382 }
2371 2383
2372 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2384 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
(...skipping 12 matching lines...) Expand all
2385 PushOperands(scratch, r2, r2, scratch); 2397 PushOperands(scratch, r2, r2, scratch);
2386 VisitForStackValue(prop->key()); 2398 VisitForStackValue(prop->key());
2387 2399
2388 // Stack here: 2400 // Stack here:
2389 // - home_object 2401 // - home_object
2390 // - this (receiver) 2402 // - this (receiver)
2391 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2403 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2392 // - home_object 2404 // - home_object
2393 // - key 2405 // - key
2394 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); 2406 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2395 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2407 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2396 2408
2397 // Replace home_object with target function. 2409 // Replace home_object with target function.
2398 __ StoreP(r2, MemOperand(sp, kPointerSize)); 2410 __ StoreP(r2, MemOperand(sp, kPointerSize));
2399 2411
2400 // Stack here: 2412 // Stack here:
2401 // - target function 2413 // - target function
2402 // - this (receiver) 2414 // - this (receiver)
2403 EmitCall(expr); 2415 EmitCall(expr);
2404 } 2416 }
2405 2417
2406 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { 2418 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
2407 // Load the arguments. 2419 // Load the arguments.
2408 ZoneList<Expression*>* args = expr->arguments(); 2420 ZoneList<Expression*>* args = expr->arguments();
2409 int arg_count = args->length(); 2421 int arg_count = args->length();
2410 for (int i = 0; i < arg_count; i++) { 2422 for (int i = 0; i < arg_count; i++) {
2411 VisitForStackValue(args->at(i)); 2423 VisitForStackValue(args->at(i));
2412 } 2424 }
2413 2425
2414 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2426 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
2415 SetCallPosition(expr, expr->tail_call_mode()); 2427 SetCallPosition(expr, expr->tail_call_mode());
2416 if (expr->tail_call_mode() == TailCallMode::kAllow) { 2428 if (expr->tail_call_mode() == TailCallMode::kAllow) {
2417 if (FLAG_trace) { 2429 if (FLAG_trace) {
2418 __ CallRuntime(Runtime::kTraceTailCall); 2430 __ CallRuntime(Runtime::kTraceTailCall);
2419 } 2431 }
2420 // Update profiling counters before the tail call since we will 2432 // Update profiling counters before the tail call since we will
2421 // not return to this function. 2433 // not return to this function.
2422 EmitProfilingCounterHandlingForReturnSequence(true); 2434 EmitProfilingCounterHandlingForReturnSequence(true);
2423 } 2435 }
2424 Handle<Code> ic = 2436 Handle<Code> ic =
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2471 // Generate code for loading from variables potentially shadowed by 2483 // Generate code for loading from variables potentially shadowed by
2472 // eval-introduced variables. 2484 // eval-introduced variables.
2473 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2485 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2474 2486
2475 __ bind(&slow); 2487 __ bind(&slow);
2476 // Call the runtime to find the function to call (returned in r2) and 2488 // Call the runtime to find the function to call (returned in r2) and
2477 // the object holding it (returned in r3). 2489 // the object holding it (returned in r3).
2478 __ Push(callee->name()); 2490 __ Push(callee->name());
2479 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2491 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2480 PushOperands(r2, r3); // Function, receiver. 2492 PushOperands(r2, r3); // Function, receiver.
2481 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2493 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2482 2494
2483 // If fast case code has been generated, emit code to push the function 2495 // If fast case code has been generated, emit code to push the function
2484 // and receiver and have the slow path jump around this code. 2496 // and receiver and have the slow path jump around this code.
2485 if (done.is_linked()) { 2497 if (done.is_linked()) {
2486 Label call; 2498 Label call;
2487 __ b(&call); 2499 __ b(&call);
2488 __ bind(&done); 2500 __ bind(&done);
2489 // Push function. 2501 // Push function.
2490 __ push(r2); 2502 __ push(r2);
2491 // Pass undefined as the receiver, which is the WithBaseObject of a 2503 // Pass undefined as the receiver, which is the WithBaseObject of a
(...skipping 27 matching lines...) Expand all
2519 2531
2520 // Push a copy of the function (found below the arguments) and 2532 // Push a copy of the function (found below the arguments) and
2521 // resolve eval. 2533 // resolve eval.
2522 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); 2534 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2523 __ push(r3); 2535 __ push(r3);
2524 EmitResolvePossiblyDirectEval(expr); 2536 EmitResolvePossiblyDirectEval(expr);
2525 2537
2526 // Touch up the stack with the resolved function. 2538 // Touch up the stack with the resolved function.
2527 __ StoreP(r2, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); 2539 __ StoreP(r2, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2528 2540
2529 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2541 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2530 2542
2531 // Record source position for debugger. 2543 // Record source position for debugger.
2532 SetCallPosition(expr); 2544 SetCallPosition(expr);
2533 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); 2545 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2534 __ mov(r2, Operand(arg_count)); 2546 __ mov(r2, Operand(arg_count));
2535 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2547 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2536 expr->tail_call_mode()), 2548 expr->tail_call_mode()),
2537 RelocInfo::CODE_TARGET); 2549 RelocInfo::CODE_TARGET);
2538 OperandStackDepthDecrement(arg_count + 1); 2550 OperandStackDepthDecrement(arg_count + 1);
2539 RecordJSReturnSite(expr); 2551 RecordJSReturnSite(expr);
(...skipping 28 matching lines...) Expand all
2568 __ mov(r2, Operand(arg_count)); 2580 __ mov(r2, Operand(arg_count));
2569 __ LoadP(r3, MemOperand(sp, arg_count * kPointerSize), r0); 2581 __ LoadP(r3, MemOperand(sp, arg_count * kPointerSize), r0);
2570 2582
2571 // Record call targets in unoptimized code. 2583 // Record call targets in unoptimized code.
2572 __ EmitLoadTypeFeedbackVector(r4); 2584 __ EmitLoadTypeFeedbackVector(r4);
2573 __ LoadSmiLiteral(r5, SmiFromSlot(expr->CallNewFeedbackSlot())); 2585 __ LoadSmiLiteral(r5, SmiFromSlot(expr->CallNewFeedbackSlot()));
2574 2586
2575 CallConstructStub stub(isolate()); 2587 CallConstructStub stub(isolate());
2576 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2588 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2577 OperandStackDepthDecrement(arg_count + 1); 2589 OperandStackDepthDecrement(arg_count + 1);
2578 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2590 PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER);
2579 RestoreContext(); 2591 RestoreContext();
2580 context()->Plug(r2); 2592 context()->Plug(r2);
2581 } 2593 }
2582 2594
2583 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2595 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2584 SuperCallReference* super_call_ref = 2596 SuperCallReference* super_call_ref =
2585 expr->expression()->AsSuperCallReference(); 2597 expr->expression()->AsSuperCallReference();
2586 DCHECK_NOT_NULL(super_call_ref); 2598 DCHECK_NOT_NULL(super_call_ref);
2587 2599
2588 // Push the super constructor target on the stack (may be null, 2600 // Push the super constructor target on the stack (may be null,
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
2975 context()->Plug(result); 2987 context()->Plug(result);
2976 } 2988 }
2977 2989
2978 void FullCodeGenerator::EmitCall(CallRuntime* expr) { 2990 void FullCodeGenerator::EmitCall(CallRuntime* expr) {
2979 ZoneList<Expression*>* args = expr->arguments(); 2991 ZoneList<Expression*>* args = expr->arguments();
2980 DCHECK_LE(2, args->length()); 2992 DCHECK_LE(2, args->length());
2981 // Push target, receiver and arguments onto the stack. 2993 // Push target, receiver and arguments onto the stack.
2982 for (Expression* const arg : *args) { 2994 for (Expression* const arg : *args) {
2983 VisitForStackValue(arg); 2995 VisitForStackValue(arg);
2984 } 2996 }
2985 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2997 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
2986 // Move target to r3. 2998 // Move target to r3.
2987 int const argc = args->length() - 2; 2999 int const argc = args->length() - 2;
2988 __ LoadP(r3, MemOperand(sp, (argc + 1) * kPointerSize)); 3000 __ LoadP(r3, MemOperand(sp, (argc + 1) * kPointerSize));
2989 // Call the target. 3001 // Call the target.
2990 __ mov(r2, Operand(argc)); 3002 __ mov(r2, Operand(argc));
2991 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3003 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2992 OperandStackDepthDecrement(argc + 1); 3004 OperandStackDepthDecrement(argc + 1);
2993 RestoreContext(); 3005 RestoreContext();
2994 // Discard the function left on TOS. 3006 // Discard the function left on TOS.
2995 context()->DropAndPlug(1, r2); 3007 context()->DropAndPlug(1, r2);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
3167 // We handle value contexts explicitly rather than simply visiting 3179 // We handle value contexts explicitly rather than simply visiting
3168 // for control and plugging the control flow into the context, 3180 // for control and plugging the control flow into the context,
3169 // because we need to prepare a pair of extra administrative AST ids 3181 // because we need to prepare a pair of extra administrative AST ids
3170 // for the optimizing compiler. 3182 // for the optimizing compiler.
3171 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3183 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3172 Label materialize_true, materialize_false, done; 3184 Label materialize_true, materialize_false, done;
3173 VisitForControl(expr->expression(), &materialize_false, 3185 VisitForControl(expr->expression(), &materialize_false,
3174 &materialize_true, &materialize_true); 3186 &materialize_true, &materialize_true);
3175 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); 3187 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3176 __ bind(&materialize_true); 3188 __ bind(&materialize_true);
3177 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3189 PrepareForBailoutForId(expr->MaterializeTrueId(),
3190 BailoutState::NO_REGISTERS);
3178 __ LoadRoot(r2, Heap::kTrueValueRootIndex); 3191 __ LoadRoot(r2, Heap::kTrueValueRootIndex);
3179 if (context()->IsStackValue()) __ push(r2); 3192 if (context()->IsStackValue()) __ push(r2);
3180 __ b(&done); 3193 __ b(&done);
3181 __ bind(&materialize_false); 3194 __ bind(&materialize_false);
3182 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3195 PrepareForBailoutForId(expr->MaterializeFalseId(),
3196 BailoutState::NO_REGISTERS);
3183 __ LoadRoot(r2, Heap::kFalseValueRootIndex); 3197 __ LoadRoot(r2, Heap::kFalseValueRootIndex);
3184 if (context()->IsStackValue()) __ push(r2); 3198 if (context()->IsStackValue()) __ push(r2);
3185 __ bind(&done); 3199 __ bind(&done);
3186 } 3200 }
3187 break; 3201 break;
3188 } 3202 }
3189 3203
3190 case Token::TYPEOF: { 3204 case Token::TYPEOF: {
3191 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 3205 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
3192 { 3206 {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3271 } 3285 }
3272 3286
3273 case VARIABLE: 3287 case VARIABLE:
3274 UNREACHABLE(); 3288 UNREACHABLE();
3275 } 3289 }
3276 } 3290 }
3277 3291
3278 // We need a second deoptimization point after loading the value 3292 // We need a second deoptimization point after loading the value
3279 // in case evaluating the property load my have a side effect. 3293 // in case evaluating the property load my have a side effect.
3280 if (assign_type == VARIABLE) { 3294 if (assign_type == VARIABLE) {
3281 PrepareForBailout(expr->expression(), TOS_REG); 3295 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER);
3282 } else { 3296 } else {
3283 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 3297 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
3284 } 3298 }
3285 3299
3286 // Inline smi case if we are in a loop. 3300 // Inline smi case if we are in a loop.
3287 Label stub_call, done; 3301 Label stub_call, done;
3288 JumpPatchSite patch_site(masm_); 3302 JumpPatchSite patch_site(masm_);
3289 3303
3290 int count_value = expr->op() == Token::INC ? 1 : -1; 3304 int count_value = expr->op() == Token::INC ? 1 : -1;
3291 if (ShouldInlineSmiCase(expr->op())) { 3305 if (ShouldInlineSmiCase(expr->op())) {
3292 Label slow; 3306 Label slow;
3293 patch_site.EmitJumpIfNotSmi(r2, &slow); 3307 patch_site.EmitJumpIfNotSmi(r2, &slow);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3325 __ BranchOnNoOverflow(&done); 3339 __ BranchOnNoOverflow(&done);
3326 // Call stub. Undo operation first. 3340 // Call stub. Undo operation first.
3327 __ SubP(r2, r2, scratch1); 3341 __ SubP(r2, r2, scratch1);
3328 __ b(&stub_call); 3342 __ b(&stub_call);
3329 __ bind(&slow); 3343 __ bind(&slow);
3330 } 3344 }
3331 3345
3332 // Convert old value into a number. 3346 // Convert old value into a number.
3333 ToNumberStub convert_stub(isolate()); 3347 ToNumberStub convert_stub(isolate());
3334 __ CallStub(&convert_stub); 3348 __ CallStub(&convert_stub);
3335 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); 3349 PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
3336 3350
3337 // Save result for postfix expressions. 3351 // Save result for postfix expressions.
3338 if (expr->is_postfix()) { 3352 if (expr->is_postfix()) {
3339 if (!context()->IsEffect()) { 3353 if (!context()->IsEffect()) {
3340 // Save the result on the stack. If we have a named or keyed property 3354 // Save the result on the stack. If we have a named or keyed property
3341 // we store the result under the receiver that is currently on top 3355 // we store the result under the receiver that is currently on top
3342 // of the stack. 3356 // of the stack.
3343 switch (assign_type) { 3357 switch (assign_type) {
3344 case VARIABLE: 3358 case VARIABLE:
3345 PushOperand(r2); 3359 PushOperand(r2);
(...skipping 26 matching lines...) Expand all
3372 __ bind(&done); 3386 __ bind(&done);
3373 3387
3374 // Store the value returned in r2. 3388 // Store the value returned in r2.
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 { 3392 {
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(r2); 3398 context.Plug(r2);
3384 } 3399 }
3385 // For all contexts except EffectConstant We have the result on 3400 // For all contexts except EffectConstant 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 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3406 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3392 Token::ASSIGN, expr->CountSlot()); 3407 Token::ASSIGN, expr->CountSlot());
3393 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3408 PrepareForBailoutForId(expr->AssignmentId(),
3409 BailoutState::TOS_REGISTER);
3394 context()->Plug(r2); 3410 context()->Plug(r2);
3395 } 3411 }
3396 break; 3412 break;
3397 case NAMED_PROPERTY: { 3413 case NAMED_PROPERTY: {
3398 __ mov(StoreDescriptor::NameRegister(), 3414 __ mov(StoreDescriptor::NameRegister(),
3399 Operand(prop->key()->AsLiteral()->value())); 3415 Operand(prop->key()->AsLiteral()->value()));
3400 PopOperand(StoreDescriptor::ReceiverRegister()); 3416 PopOperand(StoreDescriptor::ReceiverRegister());
3401 EmitLoadStoreICSlot(expr->CountSlot()); 3417 EmitLoadStoreICSlot(expr->CountSlot());
3402 CallStoreIC(); 3418 CallStoreIC();
3403 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3419 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3404 if (expr->is_postfix()) { 3420 if (expr->is_postfix()) {
3405 if (!context()->IsEffect()) { 3421 if (!context()->IsEffect()) {
3406 context()->PlugTOS(); 3422 context()->PlugTOS();
3407 } 3423 }
3408 } else { 3424 } else {
3409 context()->Plug(r2); 3425 context()->Plug(r2);
3410 } 3426 }
3411 break; 3427 break;
3412 } 3428 }
3413 case NAMED_SUPER_PROPERTY: { 3429 case NAMED_SUPER_PROPERTY: {
(...skipping 18 matching lines...) Expand all
3432 } 3448 }
3433 break; 3449 break;
3434 } 3450 }
3435 case KEYED_PROPERTY: { 3451 case KEYED_PROPERTY: {
3436 PopOperands(StoreDescriptor::ReceiverRegister(), 3452 PopOperands(StoreDescriptor::ReceiverRegister(),
3437 StoreDescriptor::NameRegister()); 3453 StoreDescriptor::NameRegister());
3438 Handle<Code> ic = 3454 Handle<Code> ic =
3439 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3455 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3440 EmitLoadStoreICSlot(expr->CountSlot()); 3456 EmitLoadStoreICSlot(expr->CountSlot());
3441 CallIC(ic); 3457 CallIC(ic);
3442 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3458 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3443 if (expr->is_postfix()) { 3459 if (expr->is_postfix()) {
3444 if (!context()->IsEffect()) { 3460 if (!context()->IsEffect()) {
3445 context()->PlugTOS(); 3461 context()->PlugTOS();
3446 } 3462 }
3447 } else { 3463 } else {
3448 context()->Plug(r2); 3464 context()->Plug(r2);
3449 } 3465 }
3450 break; 3466 break;
3451 } 3467 }
3452 } 3468 }
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
3802 DCHECK(kOSRBranchInstruction == br_instr); 3818 DCHECK(kOSRBranchInstruction == br_instr);
3803 3819
3804 DCHECK(interrupt_address == 3820 DCHECK(interrupt_address ==
3805 isolate->builtins()->OnStackReplacement()->entry()); 3821 isolate->builtins()->OnStackReplacement()->entry());
3806 return ON_STACK_REPLACEMENT; 3822 return ON_STACK_REPLACEMENT;
3807 } 3823 }
3808 3824
3809 } // namespace internal 3825 } // namespace internal
3810 } // namespace v8 3826 } // namespace v8
3811 #endif // V8_TARGET_ARCH_S390 3827 #endif // V8_TARGET_ARCH_S390
OLDNEW
« no previous file with comments | « src/full-codegen/ppc/full-codegen-ppc.cc ('k') | src/ppc/builtins-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698