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

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

Issue 1969423002: [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/full-codegen.h ('k') | src/full-codegen/ia32/full-codegen-ia32.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 #include "src/full-codegen/full-codegen.h" 5 #include "src/full-codegen/full-codegen.h"
6 6
7 #include "src/ast/ast-numbering.h" 7 #include "src/ast/ast-numbering.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/prettyprinter.h" 9 #include "src/ast/prettyprinter.h"
10 #include "src/ast/scopeinfo.h" 10 #include "src/ast/scopeinfo.h"
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 expr->values()->length() > JSArray::kInitialMaxFastElementArray; 155 expr->values()->length() > JSArray::kInitialMaxFastElementArray;
156 } 156 }
157 157
158 158
159 void FullCodeGenerator::Initialize() { 159 void FullCodeGenerator::Initialize() {
160 InitializeAstVisitor(info_->isolate()); 160 InitializeAstVisitor(info_->isolate());
161 masm_->set_emit_debug_code(FLAG_debug_code); 161 masm_->set_emit_debug_code(FLAG_debug_code);
162 masm_->set_predictable_code_size(true); 162 masm_->set_predictable_code_size(true);
163 } 163 }
164 164
165 165 void FullCodeGenerator::PrepareForBailout(Expression* node,
166 void FullCodeGenerator::PrepareForBailout(Expression* node, State state) { 166 BailoutState state) {
167 PrepareForBailoutForId(node->id(), state); 167 PrepareForBailoutForId(node->id(), state);
168 } 168 }
169 169
170 170
171 void FullCodeGenerator::CallLoadIC(TypeofMode typeof_mode, 171 void FullCodeGenerator::CallLoadIC(TypeofMode typeof_mode,
172 TypeFeedbackId id) { 172 TypeFeedbackId id) {
173 Handle<Code> ic = CodeFactory::LoadIC(isolate(), typeof_mode).code(); 173 Handle<Code> ic = CodeFactory::LoadIC(isolate(), typeof_mode).code();
174 CallIC(ic, id); 174 CallIC(ic, id);
175 } 175 }
176 176
177 177
178 void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) { 178 void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) {
179 Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code(); 179 Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code();
180 CallIC(ic, id); 180 CallIC(ic, id);
181 } 181 }
182 182
183 183
184 void FullCodeGenerator::RecordJSReturnSite(Call* call) { 184 void FullCodeGenerator::RecordJSReturnSite(Call* call) {
185 // We record the offset of the function return so we can rebuild the frame 185 // We record the offset of the function return so we can rebuild the frame
186 // if the function was inlined, i.e., this is the return address in the 186 // if the function was inlined, i.e., this is the return address in the
187 // inlined function's frame. 187 // inlined function's frame.
188 // 188 //
189 // The state is ignored. We defensively set it to TOS_REG, which is the 189 // The bailout state is ignored. We defensively set it to TOS_REGISTER, which
190 // real state of the unoptimized code at the return site. 190 // is the real state of the unoptimized code at the return site.
191 PrepareForBailoutForId(call->ReturnId(), TOS_REG); 191 PrepareForBailoutForId(call->ReturnId(), BailoutState::TOS_REGISTER);
192 #ifdef DEBUG 192 #ifdef DEBUG
193 // In debug builds, mark the return so we can verify that this function 193 // In debug builds, mark the return so we can verify that this function
194 // was called. 194 // was called.
195 DCHECK(!call->return_is_recorded_); 195 DCHECK(!call->return_is_recorded_);
196 call->return_is_recorded_ = true; 196 call->return_is_recorded_ = true;
197 #endif 197 #endif
198 } 198 }
199 199
200 200 void FullCodeGenerator::PrepareForBailoutForId(BailoutId id,
201 void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) { 201 BailoutState state) {
202 // There's no need to prepare this code for bailouts from already optimized 202 // There's no need to prepare this code for bailouts from already optimized
203 // code or code that can't be optimized. 203 // code or code that can't be optimized.
204 if (!info_->HasDeoptimizationSupport()) return; 204 if (!info_->HasDeoptimizationSupport()) return;
205 unsigned pc_and_state = 205 unsigned pc_and_state =
206 StateField::encode(state) | PcField::encode(masm_->pc_offset()); 206 BailoutStateField::encode(state) | PcField::encode(masm_->pc_offset());
207 DCHECK(Smi::IsValid(pc_and_state)); 207 DCHECK(Smi::IsValid(pc_and_state));
208 #ifdef DEBUG 208 #ifdef DEBUG
209 for (int i = 0; i < bailout_entries_.length(); ++i) { 209 for (int i = 0; i < bailout_entries_.length(); ++i) {
210 DCHECK(bailout_entries_[i].id != id); 210 DCHECK(bailout_entries_[i].id != id);
211 } 211 }
212 #endif 212 #endif
213 BailoutEntry entry = { id, pc_and_state }; 213 BailoutEntry entry = { id, pc_and_state };
214 bailout_entries_.Add(entry, zone()); 214 bailout_entries_.Add(entry, zone());
215 } 215 }
216 216
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 Label done; 743 Label done;
744 744
745 if (context()->IsTest()) { 745 if (context()->IsTest()) {
746 Label eval_right; 746 Label eval_right;
747 const TestContext* test = TestContext::cast(context()); 747 const TestContext* test = TestContext::cast(context());
748 if (is_logical_and) { 748 if (is_logical_and) {
749 VisitForControl(left, &eval_right, test->false_label(), &eval_right); 749 VisitForControl(left, &eval_right, test->false_label(), &eval_right);
750 } else { 750 } else {
751 VisitForControl(left, test->true_label(), &eval_right, &eval_right); 751 VisitForControl(left, test->true_label(), &eval_right, &eval_right);
752 } 752 }
753 PrepareForBailoutForId(right_id, NO_REGISTERS); 753 PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
754 __ bind(&eval_right); 754 __ bind(&eval_right);
755 755
756 } else if (context()->IsAccumulatorValue()) { 756 } else if (context()->IsAccumulatorValue()) {
757 VisitForAccumulatorValue(left); 757 VisitForAccumulatorValue(left);
758 // We want the value in the accumulator for the test, and on the stack in 758 // We want the value in the accumulator for the test, and on the stack in
759 // case we need it. 759 // case we need it.
760 __ Push(result_register()); 760 __ Push(result_register());
761 Label discard, restore; 761 Label discard, restore;
762 if (is_logical_and) { 762 if (is_logical_and) {
763 DoTest(left, &discard, &restore, &restore); 763 DoTest(left, &discard, &restore, &restore);
764 } else { 764 } else {
765 DoTest(left, &restore, &discard, &restore); 765 DoTest(left, &restore, &discard, &restore);
766 } 766 }
767 __ bind(&restore); 767 __ bind(&restore);
768 __ Pop(result_register()); 768 __ Pop(result_register());
769 __ jmp(&done); 769 __ jmp(&done);
770 __ bind(&discard); 770 __ bind(&discard);
771 __ Drop(1); 771 __ Drop(1);
772 PrepareForBailoutForId(right_id, NO_REGISTERS); 772 PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
773 773
774 } else if (context()->IsStackValue()) { 774 } else if (context()->IsStackValue()) {
775 VisitForAccumulatorValue(left); 775 VisitForAccumulatorValue(left);
776 // We want the value in the accumulator for the test, and on the stack in 776 // We want the value in the accumulator for the test, and on the stack in
777 // case we need it. 777 // case we need it.
778 __ Push(result_register()); 778 __ Push(result_register());
779 Label discard; 779 Label discard;
780 if (is_logical_and) { 780 if (is_logical_and) {
781 DoTest(left, &discard, &done, &discard); 781 DoTest(left, &discard, &done, &discard);
782 } else { 782 } else {
783 DoTest(left, &done, &discard, &discard); 783 DoTest(left, &done, &discard, &discard);
784 } 784 }
785 __ bind(&discard); 785 __ bind(&discard);
786 __ Drop(1); 786 __ Drop(1);
787 PrepareForBailoutForId(right_id, NO_REGISTERS); 787 PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
788 788
789 } else { 789 } else {
790 DCHECK(context()->IsEffect()); 790 DCHECK(context()->IsEffect());
791 Label eval_right; 791 Label eval_right;
792 if (is_logical_and) { 792 if (is_logical_and) {
793 VisitForControl(left, &eval_right, &done, &eval_right); 793 VisitForControl(left, &eval_right, &done, &eval_right);
794 } else { 794 } else {
795 VisitForControl(left, &done, &eval_right, &eval_right); 795 VisitForControl(left, &done, &eval_right, &eval_right);
796 } 796 }
797 PrepareForBailoutForId(right_id, NO_REGISTERS); 797 PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
798 __ bind(&eval_right); 798 __ bind(&eval_right);
799 } 799 }
800 800
801 VisitInDuplicateContext(right); 801 VisitInDuplicateContext(right);
802 __ bind(&done); 802 __ bind(&done);
803 } 803 }
804 804
805 805
806 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 806 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
807 Token::Value op = expr->op(); 807 Token::Value op = expr->op();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 PopOperand(LoadDescriptor::ReceiverRegister()); 845 PopOperand(LoadDescriptor::ReceiverRegister());
846 EmitKeyedPropertyLoad(expr); 846 EmitKeyedPropertyLoad(expr);
847 } else { 847 } else {
848 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 848 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
849 VisitForStackValue( 849 VisitForStackValue(
850 expr->obj()->AsSuperPropertyReference()->home_object()); 850 expr->obj()->AsSuperPropertyReference()->home_object());
851 VisitForStackValue(expr->key()); 851 VisitForStackValue(expr->key());
852 EmitKeyedSuperPropertyLoad(expr); 852 EmitKeyedSuperPropertyLoad(expr);
853 } 853 }
854 } 854 }
855 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 855 PrepareForBailoutForId(expr->LoadId(), BailoutState::TOS_REGISTER);
856 context()->Plug(result_register()); 856 context()->Plug(result_register());
857 } 857 }
858 858
859 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 859 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
860 VariableProxy* proxy = expr->AsVariableProxy(); 860 VariableProxy* proxy = expr->AsVariableProxy();
861 DCHECK(!context()->IsEffect()); 861 DCHECK(!context()->IsEffect());
862 DCHECK(!context()->IsTest()); 862 DCHECK(!context()->IsTest());
863 863
864 if (proxy != NULL && (proxy->var()->IsUnallocatedOrGlobalSlot() || 864 if (proxy != NULL && (proxy->var()->IsUnallocatedOrGlobalSlot() ||
865 proxy->var()->IsLookupSlot())) { 865 proxy->var()->IsLookupSlot())) {
866 EmitVariableLoad(proxy, INSIDE_TYPEOF); 866 EmitVariableLoad(proxy, INSIDE_TYPEOF);
867 PrepareForBailout(proxy, TOS_REG); 867 PrepareForBailout(proxy, BailoutState::TOS_REGISTER);
868 } else { 868 } else {
869 // This expression cannot throw a reference error at the top level. 869 // This expression cannot throw a reference error at the top level.
870 VisitInDuplicateContext(expr); 870 VisitInDuplicateContext(expr);
871 } 871 }
872 } 872 }
873 873
874 874
875 void FullCodeGenerator::VisitBlock(Block* stmt) { 875 void FullCodeGenerator::VisitBlock(Block* stmt) {
876 Comment cmnt(masm_, "[ Block"); 876 Comment cmnt(masm_, "[ Block");
877 NestedBlock nested_block(this, stmt); 877 NestedBlock nested_block(this, stmt);
(...skipping 27 matching lines...) Expand all
905 } 905 }
906 906
907 907
908 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { 908 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
909 Comment cmnt(masm_, "[ IfStatement"); 909 Comment cmnt(masm_, "[ IfStatement");
910 SetStatementPosition(stmt); 910 SetStatementPosition(stmt);
911 Label then_part, else_part, done; 911 Label then_part, else_part, done;
912 912
913 if (stmt->HasElseStatement()) { 913 if (stmt->HasElseStatement()) {
914 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); 914 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
915 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 915 PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS);
916 __ bind(&then_part); 916 __ bind(&then_part);
917 Visit(stmt->then_statement()); 917 Visit(stmt->then_statement());
918 __ jmp(&done); 918 __ jmp(&done);
919 919
920 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 920 PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS);
921 __ bind(&else_part); 921 __ bind(&else_part);
922 Visit(stmt->else_statement()); 922 Visit(stmt->else_statement());
923 } else { 923 } else {
924 VisitForControl(stmt->condition(), &then_part, &done, &then_part); 924 VisitForControl(stmt->condition(), &then_part, &done, &then_part);
925 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 925 PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS);
926 __ bind(&then_part); 926 __ bind(&then_part);
927 Visit(stmt->then_statement()); 927 Visit(stmt->then_statement());
928 928
929 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 929 PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS);
930 } 930 }
931 __ bind(&done); 931 __ bind(&done);
932 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); 932 PrepareForBailoutForId(stmt->IfId(), BailoutState::NO_REGISTERS);
933 } 933 }
934 934
935 void FullCodeGenerator::EmitContinue(Statement* target) { 935 void FullCodeGenerator::EmitContinue(Statement* target) {
936 NestedStatement* current = nesting_stack_; 936 NestedStatement* current = nesting_stack_;
937 int context_length = 0; 937 int context_length = 0;
938 // When continuing, we clobber the unpredictable value in the accumulator 938 // When continuing, we clobber the unpredictable value in the accumulator
939 // with one that's safe for GC. If we hit an exit from the try block of 939 // with one that's safe for GC. If we hit an exit from the try block of
940 // try...finally on our way out, we will unconditionally preserve the 940 // try...finally on our way out, we will unconditionally preserve the
941 // accumulator on the stack. 941 // accumulator on the stack.
942 ClearAccumulator(); 942 ClearAccumulator();
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { 1086 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
1087 // Stack: receiver, home_object, key. 1087 // Stack: receiver, home_object, key.
1088 SetExpressionPosition(prop); 1088 SetExpressionPosition(prop);
1089 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); 1089 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
1090 } 1090 }
1091 1091
1092 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, 1092 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property,
1093 BailoutId bailout_id) { 1093 BailoutId bailout_id) {
1094 VisitForStackValue(property->key()); 1094 VisitForStackValue(property->key());
1095 CallRuntimeWithOperands(Runtime::kToName); 1095 CallRuntimeWithOperands(Runtime::kToName);
1096 PrepareForBailoutForId(bailout_id, NO_REGISTERS); 1096 PrepareForBailoutForId(bailout_id, BailoutState::NO_REGISTERS);
1097 PushOperand(result_register()); 1097 PushOperand(result_register());
1098 } 1098 }
1099 1099
1100 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { 1100 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) {
1101 DCHECK(!slot.IsInvalid()); 1101 DCHECK(!slot.IsInvalid());
1102 __ Move(VectorStoreICTrampolineDescriptor::SlotRegister(), SmiFromSlot(slot)); 1102 __ Move(VectorStoreICTrampolineDescriptor::SlotRegister(), SmiFromSlot(slot));
1103 } 1103 }
1104 1104
1105 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 1105 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
1106 Comment cmnt(masm_, "[ ReturnStatement"); 1106 Comment cmnt(masm_, "[ ReturnStatement");
1107 SetStatementPosition(stmt); 1107 SetStatementPosition(stmt);
1108 Expression* expr = stmt->expression(); 1108 Expression* expr = stmt->expression();
1109 VisitForAccumulatorValue(expr); 1109 VisitForAccumulatorValue(expr);
1110 EmitUnwindAndReturn(); 1110 EmitUnwindAndReturn();
1111 } 1111 }
1112 1112
1113 1113
1114 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { 1114 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
1115 Comment cmnt(masm_, "[ WithStatement"); 1115 Comment cmnt(masm_, "[ WithStatement");
1116 SetStatementPosition(stmt); 1116 SetStatementPosition(stmt);
1117 1117
1118 VisitForAccumulatorValue(stmt->expression()); 1118 VisitForAccumulatorValue(stmt->expression());
1119 Callable callable = CodeFactory::ToObject(isolate()); 1119 Callable callable = CodeFactory::ToObject(isolate());
1120 __ Move(callable.descriptor().GetRegisterParameter(0), result_register()); 1120 __ Move(callable.descriptor().GetRegisterParameter(0), result_register());
1121 __ Call(callable.code(), RelocInfo::CODE_TARGET); 1121 __ Call(callable.code(), RelocInfo::CODE_TARGET);
1122 PrepareForBailoutForId(stmt->ToObjectId(), NO_REGISTERS); 1122 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::NO_REGISTERS);
1123 PushOperand(result_register()); 1123 PushOperand(result_register());
1124 PushFunctionArgumentForContextAllocation(); 1124 PushFunctionArgumentForContextAllocation();
1125 CallRuntimeWithOperands(Runtime::kPushWithContext); 1125 CallRuntimeWithOperands(Runtime::kPushWithContext);
1126 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1126 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1127 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 1127 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
1128 1128
1129 Scope* saved_scope = scope(); 1129 Scope* saved_scope = scope();
1130 scope_ = stmt->scope(); 1130 scope_ = stmt->scope();
1131 { WithOrCatch body(this); 1131 { WithOrCatch body(this);
1132 Visit(stmt->statement()); 1132 Visit(stmt->statement());
1133 } 1133 }
1134 scope_ = saved_scope; 1134 scope_ = saved_scope;
1135 1135
1136 // Pop context. 1136 // Pop context.
1137 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1137 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
(...skipping 11 matching lines...) Expand all
1149 1149
1150 Iteration loop_statement(this, stmt); 1150 Iteration loop_statement(this, stmt);
1151 increment_loop_depth(); 1151 increment_loop_depth();
1152 1152
1153 __ bind(&body); 1153 __ bind(&body);
1154 Visit(stmt->body()); 1154 Visit(stmt->body());
1155 1155
1156 // Record the position of the do while condition and make sure it is 1156 // Record the position of the do while condition and make sure it is
1157 // possible to break on the condition. 1157 // possible to break on the condition.
1158 __ bind(loop_statement.continue_label()); 1158 __ bind(loop_statement.continue_label());
1159 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1159 PrepareForBailoutForId(stmt->ContinueId(), BailoutState::NO_REGISTERS);
1160 1160
1161 // Here is the actual 'while' keyword. 1161 // Here is the actual 'while' keyword.
1162 SetExpressionAsStatementPosition(stmt->cond()); 1162 SetExpressionAsStatementPosition(stmt->cond());
1163 VisitForControl(stmt->cond(), 1163 VisitForControl(stmt->cond(),
1164 &book_keeping, 1164 &book_keeping,
1165 loop_statement.break_label(), 1165 loop_statement.break_label(),
1166 &book_keeping); 1166 &book_keeping);
1167 1167
1168 // Check stack before looping. 1168 // Check stack before looping.
1169 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1169 PrepareForBailoutForId(stmt->BackEdgeId(), BailoutState::NO_REGISTERS);
1170 __ bind(&book_keeping); 1170 __ bind(&book_keeping);
1171 EmitBackEdgeBookkeeping(stmt, &body); 1171 EmitBackEdgeBookkeeping(stmt, &body);
1172 __ jmp(&body); 1172 __ jmp(&body);
1173 1173
1174 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1174 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
1175 __ bind(loop_statement.break_label()); 1175 __ bind(loop_statement.break_label());
1176 decrement_loop_depth(); 1176 decrement_loop_depth();
1177 } 1177 }
1178 1178
1179 1179
1180 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1180 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1181 Comment cmnt(masm_, "[ WhileStatement"); 1181 Comment cmnt(masm_, "[ WhileStatement");
1182 Label loop, body; 1182 Label loop, body;
1183 1183
1184 Iteration loop_statement(this, stmt); 1184 Iteration loop_statement(this, stmt);
1185 increment_loop_depth(); 1185 increment_loop_depth();
1186 1186
1187 __ bind(&loop); 1187 __ bind(&loop);
1188 1188
1189 SetExpressionAsStatementPosition(stmt->cond()); 1189 SetExpressionAsStatementPosition(stmt->cond());
1190 VisitForControl(stmt->cond(), 1190 VisitForControl(stmt->cond(),
1191 &body, 1191 &body,
1192 loop_statement.break_label(), 1192 loop_statement.break_label(),
1193 &body); 1193 &body);
1194 1194
1195 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1195 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
1196 __ bind(&body); 1196 __ bind(&body);
1197 Visit(stmt->body()); 1197 Visit(stmt->body());
1198 1198
1199 __ bind(loop_statement.continue_label()); 1199 __ bind(loop_statement.continue_label());
1200 1200
1201 // Check stack before looping. 1201 // Check stack before looping.
1202 EmitBackEdgeBookkeeping(stmt, &loop); 1202 EmitBackEdgeBookkeeping(stmt, &loop);
1203 __ jmp(&loop); 1203 __ jmp(&loop);
1204 1204
1205 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1205 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
1206 __ bind(loop_statement.break_label()); 1206 __ bind(loop_statement.break_label());
1207 decrement_loop_depth(); 1207 decrement_loop_depth();
1208 } 1208 }
1209 1209
1210 1210
1211 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1211 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1212 Comment cmnt(masm_, "[ ForStatement"); 1212 Comment cmnt(masm_, "[ ForStatement");
1213 // Do not insert break location as we do it below. 1213 // Do not insert break location as we do it below.
1214 SetStatementPosition(stmt, SKIP_BREAK); 1214 SetStatementPosition(stmt, SKIP_BREAK);
1215 1215
1216 Label test, body; 1216 Label test, body;
1217 1217
1218 Iteration loop_statement(this, stmt); 1218 Iteration loop_statement(this, stmt);
1219 1219
1220 if (stmt->init() != NULL) { 1220 if (stmt->init() != NULL) {
1221 Visit(stmt->init()); 1221 Visit(stmt->init());
1222 } 1222 }
1223 1223
1224 increment_loop_depth(); 1224 increment_loop_depth();
1225 // Emit the test at the bottom of the loop (even if empty). 1225 // Emit the test at the bottom of the loop (even if empty).
1226 __ jmp(&test); 1226 __ jmp(&test);
1227 1227
1228 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1228 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
1229 __ bind(&body); 1229 __ bind(&body);
1230 Visit(stmt->body()); 1230 Visit(stmt->body());
1231 1231
1232 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1232 PrepareForBailoutForId(stmt->ContinueId(), BailoutState::NO_REGISTERS);
1233 __ bind(loop_statement.continue_label()); 1233 __ bind(loop_statement.continue_label());
1234 if (stmt->next() != NULL) { 1234 if (stmt->next() != NULL) {
1235 SetStatementPosition(stmt->next()); 1235 SetStatementPosition(stmt->next());
1236 Visit(stmt->next()); 1236 Visit(stmt->next());
1237 } 1237 }
1238 1238
1239 // Check stack before looping. 1239 // Check stack before looping.
1240 EmitBackEdgeBookkeeping(stmt, &body); 1240 EmitBackEdgeBookkeeping(stmt, &body);
1241 1241
1242 __ bind(&test); 1242 __ bind(&test);
1243 if (stmt->cond() != NULL) { 1243 if (stmt->cond() != NULL) {
1244 SetExpressionAsStatementPosition(stmt->cond()); 1244 SetExpressionAsStatementPosition(stmt->cond());
1245 VisitForControl(stmt->cond(), 1245 VisitForControl(stmt->cond(),
1246 &body, 1246 &body,
1247 loop_statement.break_label(), 1247 loop_statement.break_label(),
1248 loop_statement.break_label()); 1248 loop_statement.break_label());
1249 } else { 1249 } else {
1250 __ jmp(&body); 1250 __ jmp(&body);
1251 } 1251 }
1252 1252
1253 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1253 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
1254 __ bind(loop_statement.break_label()); 1254 __ bind(loop_statement.break_label());
1255 decrement_loop_depth(); 1255 decrement_loop_depth();
1256 } 1256 }
1257 1257
1258 1258
1259 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 1259 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1260 Comment cmnt(masm_, "[ ForOfStatement"); 1260 Comment cmnt(masm_, "[ ForOfStatement");
1261 1261
1262 Iteration loop_statement(this, stmt); 1262 Iteration loop_statement(this, stmt);
1263 increment_loop_depth(); 1263 increment_loop_depth();
(...skipping 15 matching lines...) Expand all
1279 &result_not_done, &result_not_done); 1279 &result_not_done, &result_not_done);
1280 __ bind(&result_not_done); 1280 __ bind(&result_not_done);
1281 1281
1282 // each = result.value 1282 // each = result.value
1283 VisitForEffect(stmt->assign_each()); 1283 VisitForEffect(stmt->assign_each());
1284 1284
1285 // Generate code for the body of the loop. 1285 // Generate code for the body of the loop.
1286 Visit(stmt->body()); 1286 Visit(stmt->body());
1287 1287
1288 // Check stack before looping. 1288 // Check stack before looping.
1289 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1289 PrepareForBailoutForId(stmt->BackEdgeId(), BailoutState::NO_REGISTERS);
1290 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); 1290 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
1291 __ jmp(loop_statement.continue_label()); 1291 __ jmp(loop_statement.continue_label());
1292 1292
1293 // Exit and decrement the loop depth. 1293 // Exit and decrement the loop depth.
1294 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1294 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
1295 __ bind(loop_statement.break_label()); 1295 __ bind(loop_statement.break_label());
1296 decrement_loop_depth(); 1296 decrement_loop_depth();
1297 } 1297 }
1298 1298
1299 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 1299 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
1300 LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset, 1300 LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset,
1301 result_register()); 1301 result_register());
1302 context()->Plug(result_register()); 1302 context()->Plug(result_register());
1303 } 1303 }
1304 1304
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1428 } 1428 }
1429 1429
1430 1430
1431 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1431 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1432 Comment cmnt(masm_, "[ DebuggerStatement"); 1432 Comment cmnt(masm_, "[ DebuggerStatement");
1433 SetStatementPosition(stmt); 1433 SetStatementPosition(stmt);
1434 1434
1435 __ DebugBreak(); 1435 __ DebugBreak();
1436 // Ignore the return value. 1436 // Ignore the return value.
1437 1437
1438 PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS); 1438 PrepareForBailoutForId(stmt->DebugBreakId(), BailoutState::NO_REGISTERS);
1439 } 1439 }
1440 1440
1441 1441
1442 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) { 1442 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) {
1443 UNREACHABLE(); 1443 UNREACHABLE();
1444 } 1444 }
1445 1445
1446 1446
1447 void FullCodeGenerator::VisitConditional(Conditional* expr) { 1447 void FullCodeGenerator::VisitConditional(Conditional* expr) {
1448 Comment cmnt(masm_, "[ Conditional"); 1448 Comment cmnt(masm_, "[ Conditional");
1449 Label true_case, false_case, done; 1449 Label true_case, false_case, done;
1450 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); 1450 VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
1451 1451
1452 int original_stack_depth = operand_stack_depth_; 1452 int original_stack_depth = operand_stack_depth_;
1453 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); 1453 PrepareForBailoutForId(expr->ThenId(), BailoutState::NO_REGISTERS);
1454 __ bind(&true_case); 1454 __ bind(&true_case);
1455 SetExpressionPosition(expr->then_expression()); 1455 SetExpressionPosition(expr->then_expression());
1456 if (context()->IsTest()) { 1456 if (context()->IsTest()) {
1457 const TestContext* for_test = TestContext::cast(context()); 1457 const TestContext* for_test = TestContext::cast(context());
1458 VisitForControl(expr->then_expression(), 1458 VisitForControl(expr->then_expression(),
1459 for_test->true_label(), 1459 for_test->true_label(),
1460 for_test->false_label(), 1460 for_test->false_label(),
1461 NULL); 1461 NULL);
1462 } else { 1462 } else {
1463 VisitInDuplicateContext(expr->then_expression()); 1463 VisitInDuplicateContext(expr->then_expression());
1464 __ jmp(&done); 1464 __ jmp(&done);
1465 } 1465 }
1466 1466
1467 operand_stack_depth_ = original_stack_depth; 1467 operand_stack_depth_ = original_stack_depth;
1468 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); 1468 PrepareForBailoutForId(expr->ElseId(), BailoutState::NO_REGISTERS);
1469 __ bind(&false_case); 1469 __ bind(&false_case);
1470 SetExpressionPosition(expr->else_expression()); 1470 SetExpressionPosition(expr->else_expression());
1471 VisitInDuplicateContext(expr->else_expression()); 1471 VisitInDuplicateContext(expr->else_expression());
1472 // If control flow falls through Visit, merge it with true case here. 1472 // If control flow falls through Visit, merge it with true case here.
1473 if (!context()->IsTest()) { 1473 if (!context()->IsTest()) {
1474 __ bind(&done); 1474 __ bind(&done);
1475 } 1475 }
1476 } 1476 }
1477 1477
1478 1478
(...skipping 30 matching lines...) Expand all
1509 } else { 1509 } else {
1510 PushOperand(isolate()->factory()->the_hole_value()); 1510 PushOperand(isolate()->factory()->the_hole_value());
1511 } 1511 }
1512 1512
1513 VisitForStackValue(lit->constructor()); 1513 VisitForStackValue(lit->constructor());
1514 1514
1515 PushOperand(Smi::FromInt(lit->start_position())); 1515 PushOperand(Smi::FromInt(lit->start_position()));
1516 PushOperand(Smi::FromInt(lit->end_position())); 1516 PushOperand(Smi::FromInt(lit->end_position()));
1517 1517
1518 CallRuntimeWithOperands(Runtime::kDefineClass); 1518 CallRuntimeWithOperands(Runtime::kDefineClass);
1519 PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG); 1519 PrepareForBailoutForId(lit->CreateLiteralId(), BailoutState::TOS_REGISTER);
1520 PushOperand(result_register()); 1520 PushOperand(result_register());
1521 1521
1522 // Load the "prototype" from the constructor. 1522 // Load the "prototype" from the constructor.
1523 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); 1523 __ Move(LoadDescriptor::ReceiverRegister(), result_register());
1524 __ LoadRoot(LoadDescriptor::NameRegister(), 1524 __ LoadRoot(LoadDescriptor::NameRegister(),
1525 Heap::kprototype_stringRootIndex); 1525 Heap::kprototype_stringRootIndex);
1526 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot())); 1526 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot()));
1527 CallLoadIC(NOT_INSIDE_TYPEOF); 1527 CallLoadIC(NOT_INSIDE_TYPEOF);
1528 PrepareForBailoutForId(lit->PrototypeId(), TOS_REG); 1528 PrepareForBailoutForId(lit->PrototypeId(), BailoutState::TOS_REGISTER);
1529 PushOperand(result_register()); 1529 PushOperand(result_register());
1530 1530
1531 EmitClassDefineProperties(lit); 1531 EmitClassDefineProperties(lit);
1532 DropOperands(1); 1532 DropOperands(1);
1533 1533
1534 // Set the constructor to have fast properties. 1534 // Set the constructor to have fast properties.
1535 CallRuntimeWithOperands(Runtime::kToFastProperties); 1535 CallRuntimeWithOperands(Runtime::kToFastProperties);
1536 1536
1537 if (lit->class_variable_proxy() != nullptr) { 1537 if (lit->class_variable_proxy() != nullptr) {
1538 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT, 1538 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT,
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 1659
1660 if (expr->is_jsruntime()) { 1660 if (expr->is_jsruntime()) {
1661 Comment cmnt(masm_, "[ CallRuntime"); 1661 Comment cmnt(masm_, "[ CallRuntime");
1662 EmitLoadJSRuntimeFunction(expr); 1662 EmitLoadJSRuntimeFunction(expr);
1663 1663
1664 // Push the arguments ("left-to-right"). 1664 // Push the arguments ("left-to-right").
1665 for (int i = 0; i < arg_count; i++) { 1665 for (int i = 0; i < arg_count; i++) {
1666 VisitForStackValue(args->at(i)); 1666 VisitForStackValue(args->at(i));
1667 } 1667 }
1668 1668
1669 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 1669 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
1670 EmitCallJSRuntimeFunction(expr); 1670 EmitCallJSRuntimeFunction(expr);
1671 context()->DropAndPlug(1, result_register()); 1671 context()->DropAndPlug(1, result_register());
1672 1672
1673 } else { 1673 } else {
1674 const Runtime::Function* function = expr->function(); 1674 const Runtime::Function* function = expr->function();
1675 switch (function->function_id) { 1675 switch (function->function_id) {
1676 #define CALL_INTRINSIC_GENERATOR(Name) \ 1676 #define CALL_INTRINSIC_GENERATOR(Name) \
1677 case Runtime::kInline##Name: { \ 1677 case Runtime::kInline##Name: { \
1678 Comment cmnt(masm_, "[ Inline" #Name); \ 1678 Comment cmnt(masm_, "[ Inline" #Name); \
1679 return Emit##Name(expr); \ 1679 return Emit##Name(expr); \
1680 } 1680 }
1681 FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR) 1681 FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
1682 #undef CALL_INTRINSIC_GENERATOR 1682 #undef CALL_INTRINSIC_GENERATOR
1683 default: { 1683 default: {
1684 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 1684 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
1685 // Push the arguments ("left-to-right"). 1685 // Push the arguments ("left-to-right").
1686 for (int i = 0; i < arg_count; i++) { 1686 for (int i = 0; i < arg_count; i++) {
1687 VisitForStackValue(args->at(i)); 1687 VisitForStackValue(args->at(i));
1688 } 1688 }
1689 1689
1690 // Call the C runtime function. 1690 // Call the C runtime function.
1691 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 1691 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
1692 __ CallRuntime(expr->function(), arg_count); 1692 __ CallRuntime(expr->function(), arg_count);
1693 OperandStackDepthDecrement(arg_count); 1693 OperandStackDepthDecrement(arg_count);
1694 context()->Plug(result_register()); 1694 context()->Plug(result_register());
1695 } 1695 }
1696 } 1696 }
1697 } 1697 }
1698 } 1698 }
1699 1699
1700 void FullCodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } 1700 void FullCodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); }
1701 1701
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1870 #endif // DEBUG 1870 #endif // DEBUG
1871 1871
1872 1872
1873 FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded( 1873 FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded(
1874 FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id, 1874 FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id,
1875 BailoutId declarations_id, BailoutId exit_id) 1875 BailoutId declarations_id, BailoutId exit_id)
1876 : codegen_(codegen), exit_id_(exit_id) { 1876 : codegen_(codegen), exit_id_(exit_id) {
1877 saved_scope_ = codegen_->scope(); 1877 saved_scope_ = codegen_->scope();
1878 1878
1879 if (scope == NULL) { 1879 if (scope == NULL) {
1880 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); 1880 codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS);
1881 needs_block_context_ = false; 1881 needs_block_context_ = false;
1882 } else { 1882 } else {
1883 needs_block_context_ = scope->NeedsContext(); 1883 needs_block_context_ = scope->NeedsContext();
1884 codegen_->scope_ = scope; 1884 codegen_->scope_ = scope;
1885 { 1885 {
1886 if (needs_block_context_) { 1886 if (needs_block_context_) {
1887 Comment cmnt(masm(), "[ Extend block context"); 1887 Comment cmnt(masm(), "[ Extend block context");
1888 codegen_->PushOperand(scope->GetScopeInfo(codegen->isolate())); 1888 codegen_->PushOperand(scope->GetScopeInfo(codegen->isolate()));
1889 codegen_->PushFunctionArgumentForContextAllocation(); 1889 codegen_->PushFunctionArgumentForContextAllocation();
1890 codegen_->CallRuntimeWithOperands(Runtime::kPushBlockContext); 1890 codegen_->CallRuntimeWithOperands(Runtime::kPushBlockContext);
1891 1891
1892 // Replace the context stored in the frame. 1892 // Replace the context stored in the frame.
1893 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, 1893 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
1894 codegen_->context_register()); 1894 codegen_->context_register());
1895 } 1895 }
1896 CHECK_EQ(0, scope->num_stack_slots()); 1896 CHECK_EQ(0, scope->num_stack_slots());
1897 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); 1897 codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS);
1898 } 1898 }
1899 { 1899 {
1900 Comment cmnt(masm(), "[ Declarations"); 1900 Comment cmnt(masm(), "[ Declarations");
1901 codegen_->VisitDeclarations(scope->declarations()); 1901 codegen_->VisitDeclarations(scope->declarations());
1902 codegen_->PrepareForBailoutForId(declarations_id, NO_REGISTERS); 1902 codegen_->PrepareForBailoutForId(declarations_id,
1903 BailoutState::NO_REGISTERS);
1903 } 1904 }
1904 } 1905 }
1905 } 1906 }
1906 1907
1907 1908
1908 FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() { 1909 FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() {
1909 if (needs_block_context_) { 1910 if (needs_block_context_) {
1910 codegen_->LoadContextField(codegen_->context_register(), 1911 codegen_->LoadContextField(codegen_->context_register(),
1911 Context::PREVIOUS_INDEX); 1912 Context::PREVIOUS_INDEX);
1912 // Update local stack frame context field. 1913 // Update local stack frame context field.
1913 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, 1914 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
1914 codegen_->context_register()); 1915 codegen_->context_register());
1915 } 1916 }
1916 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS); 1917 codegen_->PrepareForBailoutForId(exit_id_, BailoutState::NO_REGISTERS);
1917 codegen_->scope_ = saved_scope_; 1918 codegen_->scope_ = saved_scope_;
1918 } 1919 }
1919 1920
1920 1921
1921 bool FullCodeGenerator::NeedsHoleCheckForLoad(VariableProxy* proxy) { 1922 bool FullCodeGenerator::NeedsHoleCheckForLoad(VariableProxy* proxy) {
1922 Variable* var = proxy->var(); 1923 Variable* var = proxy->var();
1923 1924
1924 if (!var->binding_needs_init()) { 1925 if (!var->binding_needs_init()) {
1925 return false; 1926 return false;
1926 } 1927 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 return var->scope()->is_nonlinear() || 1976 return var->scope()->is_nonlinear() ||
1976 var->initializer_position() >= proxy->position(); 1977 var->initializer_position() >= proxy->position();
1977 } 1978 }
1978 1979
1979 1980
1980 #undef __ 1981 #undef __
1981 1982
1982 1983
1983 } // namespace internal 1984 } // namespace internal
1984 } // namespace v8 1985 } // namespace v8
OLDNEW
« no previous file with comments | « src/full-codegen/full-codegen.h ('k') | src/full-codegen/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698