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

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

Issue 1218493005: Debugger: use debug break slots instead of ICs (except for calls). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: addressed comments Created 5 years, 5 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.h ('k') | src/ia32/debug-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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/ast.h" 7 #include "src/ast.h"
8 #include "src/ast-numbering.h" 8 #include "src/ast-numbering.h"
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
11 #include "src/compiler.h" 11 #include "src/compiler.h"
12 #include "src/debug.h" 12 #include "src/debug.h"
13 #include "src/full-codegen.h" 13 #include "src/full-codegen.h"
14 #include "src/liveedit.h" 14 #include "src/liveedit.h"
15 #include "src/macro-assembler.h" 15 #include "src/macro-assembler.h"
16 #include "src/prettyprinter.h" 16 #include "src/prettyprinter.h"
17 #include "src/scopeinfo.h" 17 #include "src/scopeinfo.h"
18 #include "src/scopes.h" 18 #include "src/scopes.h"
19 #include "src/snapshot/snapshot.h" 19 #include "src/snapshot/snapshot.h"
20 20
21 namespace v8 { 21 namespace v8 {
22 namespace internal { 22 namespace internal {
23 23
24 void BreakableStatementChecker::Check(Statement* stmt) {
25 Visit(stmt);
26 }
27
28
29 void BreakableStatementChecker::Check(Expression* expr) {
30 Visit(expr);
31 }
32
33
34 void BreakableStatementChecker::VisitVariableDeclaration(
35 VariableDeclaration* decl) {
36 }
37
38
39 void BreakableStatementChecker::VisitFunctionDeclaration(
40 FunctionDeclaration* decl) {
41 }
42
43
44 void BreakableStatementChecker::VisitImportDeclaration(
45 ImportDeclaration* decl) {
46 }
47
48
49 void BreakableStatementChecker::VisitExportDeclaration(
50 ExportDeclaration* decl) {
51 }
52
53
54 void BreakableStatementChecker::VisitBlock(Block* stmt) {
55 }
56
57
58 void BreakableStatementChecker::VisitExpressionStatement(
59 ExpressionStatement* stmt) {
60 // Check if expression is breakable.
61 Visit(stmt->expression());
62 }
63
64
65 void BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) {
66 }
67
68
69 void BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) {
70 // If the condition is breakable the if statement is breakable.
71 Visit(stmt->condition());
72 }
73
74
75 void BreakableStatementChecker::VisitContinueStatement(
76 ContinueStatement* stmt) {
77 }
78
79
80 void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) {
81 }
82
83
84 void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) {
85 // Return is breakable if the expression is.
86 Visit(stmt->expression());
87 }
88
89
90 void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) {
91 Visit(stmt->expression());
92 }
93
94
95 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
96 // Switch statements breakable if the tag expression is.
97 Visit(stmt->tag());
98 }
99
100
101 void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
102 // Mark do while as breakable to avoid adding a break slot in front of it.
103 is_breakable_ = true;
104 }
105
106
107 void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) {
108 // Mark while statements breakable if the condition expression is.
109 Visit(stmt->cond());
110 }
111
112
113 void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
114 // We set positions for both init and condition, if they exist.
115 if (stmt->cond() != NULL || stmt->init() != NULL) is_breakable_ = true;
116 }
117
118
119 void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
120 // For-in is breakable because we set the position for the enumerable.
121 is_breakable_ = true;
122 }
123
124
125 void BreakableStatementChecker::VisitForOfStatement(ForOfStatement* stmt) {
126 // For-of is breakable because we set the position for the next() call.
127 is_breakable_ = true;
128 }
129
130
131 void BreakableStatementChecker::VisitTryCatchStatement(
132 TryCatchStatement* stmt) {
133 // Mark try catch as breakable to avoid adding a break slot in front of it.
134 is_breakable_ = true;
135 }
136
137
138 void BreakableStatementChecker::VisitTryFinallyStatement(
139 TryFinallyStatement* stmt) {
140 // Mark try finally as breakable to avoid adding a break slot in front of it.
141 is_breakable_ = true;
142 }
143
144
145 void BreakableStatementChecker::VisitDebuggerStatement(
146 DebuggerStatement* stmt) {
147 // The debugger statement is breakable.
148 is_breakable_ = true;
149 }
150
151
152 void BreakableStatementChecker::VisitCaseClause(CaseClause* clause) {
153 }
154
155
156 void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
157 }
158
159
160 void BreakableStatementChecker::VisitClassLiteral(ClassLiteral* expr) {
161 if (expr->extends() != NULL) {
162 Visit(expr->extends());
163 }
164 }
165
166
167 void BreakableStatementChecker::VisitNativeFunctionLiteral(
168 NativeFunctionLiteral* expr) {
169 }
170
171
172 void BreakableStatementChecker::VisitConditional(Conditional* expr) {
173 }
174
175
176 void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) {
177 }
178
179
180 void BreakableStatementChecker::VisitLiteral(Literal* expr) {
181 }
182
183
184 void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
185 }
186
187
188 void BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) {
189 }
190
191
192 void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) {
193 }
194
195
196 void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
197 // If assigning to a property (including a global property) the assignment is
198 // breakable.
199 VariableProxy* proxy = expr->target()->AsVariableProxy();
200 Property* prop = expr->target()->AsProperty();
201 if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) {
202 is_breakable_ = true;
203 return;
204 }
205
206 // Otherwise the assignment is breakable if the assigned value is.
207 Visit(expr->value());
208 }
209
210
211 void BreakableStatementChecker::VisitYield(Yield* expr) {
212 // Yield is breakable if the expression is.
213 Visit(expr->expression());
214 }
215
216
217 void BreakableStatementChecker::VisitThrow(Throw* expr) {
218 // Throw is breakable if the expression is.
219 Visit(expr->exception());
220 }
221
222
223 void BreakableStatementChecker::VisitProperty(Property* expr) {
224 // Property load is breakable.
225 is_breakable_ = true;
226 }
227
228
229 void BreakableStatementChecker::VisitCall(Call* expr) {
230 // Function calls both through IC and call stub are breakable.
231 is_breakable_ = true;
232 }
233
234
235 void BreakableStatementChecker::VisitCallNew(CallNew* expr) {
236 // Function calls through new are breakable.
237 is_breakable_ = true;
238 }
239
240
241 void BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) {
242 }
243
244
245 void BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) {
246 Visit(expr->expression());
247 }
248
249
250 void BreakableStatementChecker::VisitCountOperation(CountOperation* expr) {
251 Visit(expr->expression());
252 }
253
254
255 void BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) {
256 Visit(expr->left());
257 if (expr->op() != Token::AND &&
258 expr->op() != Token::OR) {
259 Visit(expr->right());
260 }
261 }
262
263
264 void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) {
265 Visit(expr->left());
266 Visit(expr->right());
267 }
268
269
270 void BreakableStatementChecker::VisitSpread(Spread* expr) {
271 Visit(expr->expression());
272 }
273
274
275 void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
276 }
277
278
279 void BreakableStatementChecker::VisitSuperPropertyReference(
280 SuperPropertyReference* expr) {}
281
282
283 void BreakableStatementChecker::VisitSuperCallReference(
284 SuperCallReference* expr) {}
285
286
287 #define __ ACCESS_MASM(masm()) 24 #define __ ACCESS_MASM(masm())
288 25
289 bool FullCodeGenerator::MakeCode(CompilationInfo* info) { 26 bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
290 Isolate* isolate = info->isolate(); 27 Isolate* isolate = info->isolate();
291 28
292 TimerEventScope<TimerEventCompileFullCode> timer(info->isolate()); 29 TimerEventScope<TimerEventCompileFullCode> timer(info->isolate());
293 30
294 // Ensure that the feedback vector is large enough. 31 // Ensure that the feedback vector is large enough.
295 info->EnsureFeedbackVector(); 32 info->EnsureFeedbackVector();
296 33
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 400
664 401
665 int FullCodeGenerator::DeclareGlobalsFlags() { 402 int FullCodeGenerator::DeclareGlobalsFlags() {
666 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode())); 403 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode()));
667 return DeclareGlobalsEvalFlag::encode(is_eval()) | 404 return DeclareGlobalsEvalFlag::encode(is_eval()) |
668 DeclareGlobalsNativeFlag::encode(is_native()) | 405 DeclareGlobalsNativeFlag::encode(is_native()) |
669 DeclareGlobalsLanguageMode::encode(language_mode()); 406 DeclareGlobalsLanguageMode::encode(language_mode());
670 } 407 }
671 408
672 409
410 bool RecordStatementPosition(MacroAssembler* masm, int pos) {
411 if (pos == RelocInfo::kNoPosition) return false;
412 masm->positions_recorder()->RecordStatementPosition(pos);
413 masm->positions_recorder()->RecordPosition(pos);
414 return masm->positions_recorder()->WriteRecordedPositions();
415 }
416
417
418 bool RecordPosition(MacroAssembler* masm, int pos) {
419 if (pos == RelocInfo::kNoPosition) return false;
420 masm->positions_recorder()->RecordPosition(pos);
421 return masm->positions_recorder()->WriteRecordedPositions();
422 }
423
424
673 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 425 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
674 CodeGenerator::RecordPositions(masm_, fun->start_position()); 426 RecordPosition(masm_, fun->start_position());
675 } 427 }
676 428
677 429
678 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 430 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
679 CodeGenerator::RecordPositions(masm_, fun->end_position() - 1); 431 RecordStatementPosition(masm_, fun->end_position() - 1);
680 } 432 }
681 433
682 434
683 void FullCodeGenerator::SetStatementPosition(Statement* stmt) { 435 void FullCodeGenerator::SetStatementPosition(
684 if (!info_->is_debug()) { 436 Statement* stmt, FullCodeGenerator::InsertBreak insert_break) {
685 CodeGenerator::RecordPositions(masm_, stmt->position()); 437 if (stmt->position() == RelocInfo::kNoPosition) return;
686 } else { 438 bool recorded = RecordStatementPosition(masm_, stmt->position());
687 // Check if the statement will be breakable without adding a debug break 439 if (recorded && insert_break == INSERT_BREAK && info_->is_debug() &&
688 // slot. 440 !stmt->IsDebuggerStatement()) {
689 BreakableStatementChecker checker(info_->isolate(), zone()); 441 DebugCodegen::GenerateSlot(masm_);
690 checker.Check(stmt);
691 // Record the statement position right here if the statement is not
692 // breakable. For breakable statements the actual recording of the
693 // position will be postponed to the breakable code (typically an IC).
694 bool position_recorded = CodeGenerator::RecordPositions(
695 masm_, stmt->position(), !checker.is_breakable());
696 // If the position recording did record a new position generate a debug
697 // break slot to make the statement breakable.
698 if (position_recorded) {
699 DebugCodegen::GenerateSlot(masm_);
700 }
701 } 442 }
702 } 443 }
703 444
704 445
446 void FullCodeGenerator::SetExpressionPosition(
447 Expression* expr, FullCodeGenerator::InsertBreak insert_break) {
448 if (expr->position() == RelocInfo::kNoPosition) return;
449 bool recorded = RecordPosition(masm_, expr->position());
450 if (recorded && insert_break == INSERT_BREAK && info_->is_debug()) {
451 DebugCodegen::GenerateSlot(masm_);
452 }
453 }
454
455
456 void FullCodeGenerator::SetExpressionAsStatementPosition(Expression* expr) {
457 if (expr->position() == RelocInfo::kNoPosition) return;
458 bool recorded = RecordStatementPosition(masm_, expr->position());
459 if (recorded && info_->is_debug()) DebugCodegen::GenerateSlot(masm_);
460 }
461
462
705 void FullCodeGenerator::VisitSuperPropertyReference( 463 void FullCodeGenerator::VisitSuperPropertyReference(
706 SuperPropertyReference* super) { 464 SuperPropertyReference* super) {
707 __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); 465 __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
708 } 466 }
709 467
710 468
711 void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) { 469 void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) {
712 __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); 470 __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
713 } 471 }
714 472
715 473
716 void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
717 if (!info_->is_debug()) {
718 CodeGenerator::RecordPositions(masm_, expr->position());
719 } else {
720 // Check if the expression will be breakable without adding a debug break
721 // slot.
722 BreakableStatementChecker checker(info_->isolate(), zone());
723 checker.Check(expr);
724 // Record a statement position right here if the expression is not
725 // breakable. For breakable expressions the actual recording of the
726 // position will be postponed to the breakable code (typically an IC).
727 // NOTE this will record a statement position for something which might
728 // not be a statement. As stepping in the debugger will only stop at
729 // statement positions this is used for e.g. the condition expression of
730 // a do while loop.
731 bool position_recorded = CodeGenerator::RecordPositions(
732 masm_, expr->position(), !checker.is_breakable());
733 // If the position recording did record a new position generate a debug
734 // break slot to make the statement breakable.
735 if (position_recorded) {
736 DebugCodegen::GenerateSlot(masm_);
737 }
738 }
739 }
740
741
742 void FullCodeGenerator::SetSourcePosition(int pos) {
743 if (pos != RelocInfo::kNoPosition) {
744 masm_->positions_recorder()->RecordPosition(pos);
745 }
746 }
747
748
749 void FullCodeGenerator::EmitGeneratorNext(CallRuntime* expr) { 474 void FullCodeGenerator::EmitGeneratorNext(CallRuntime* expr) {
750 ZoneList<Expression*>* args = expr->arguments(); 475 ZoneList<Expression*>* args = expr->arguments();
751 DCHECK(args->length() == 2); 476 DCHECK(args->length() == 2);
752 EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::NEXT); 477 EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::NEXT);
753 } 478 }
754 479
755 480
756 void FullCodeGenerator::EmitGeneratorThrow(CallRuntime* expr) { 481 void FullCodeGenerator::EmitGeneratorThrow(CallRuntime* expr) {
757 ZoneList<Expression*>* args = expr->arguments(); 482 ZoneList<Expression*>* args = expr->arguments();
758 DCHECK(args->length() == 2); 483 DCHECK(args->length() == 2);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 596
872 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 597 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
873 Token::Value op = expr->op(); 598 Token::Value op = expr->op();
874 Comment cmnt(masm_, "[ ArithmeticExpression"); 599 Comment cmnt(masm_, "[ ArithmeticExpression");
875 Expression* left = expr->left(); 600 Expression* left = expr->left();
876 Expression* right = expr->right(); 601 Expression* right = expr->right();
877 602
878 VisitForStackValue(left); 603 VisitForStackValue(left);
879 VisitForAccumulatorValue(right); 604 VisitForAccumulatorValue(right);
880 605
881 SetSourcePosition(expr->position()); 606 SetExpressionPosition(expr);
882 if (ShouldInlineSmiCase(op)) { 607 if (ShouldInlineSmiCase(op)) {
883 EmitInlineSmiBinaryOp(expr, op, left, right); 608 EmitInlineSmiBinaryOp(expr, op, left, right);
884 } else { 609 } else {
885 EmitBinaryOp(expr, op); 610 EmitBinaryOp(expr, op);
886 } 611 }
887 } 612 }
888 613
889 614
890 void FullCodeGenerator::VisitBlock(Block* stmt) { 615 void FullCodeGenerator::VisitBlock(Block* stmt) {
891 Comment cmnt(masm_, "[ Block"); 616 Comment cmnt(masm_, "[ Block");
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 778
1054 // Pop context. 779 // Pop context.
1055 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 780 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1056 // Update local stack frame context field. 781 // Update local stack frame context field.
1057 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 782 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1058 } 783 }
1059 784
1060 785
1061 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 786 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1062 Comment cmnt(masm_, "[ DoWhileStatement"); 787 Comment cmnt(masm_, "[ DoWhileStatement");
1063 SetStatementPosition(stmt); 788 // Do not insert break location as we do that below.
789 SetStatementPosition(stmt, SKIP_BREAK);
790
1064 Label body, book_keeping; 791 Label body, book_keeping;
1065 792
1066 Iteration loop_statement(this, stmt); 793 Iteration loop_statement(this, stmt);
1067 increment_loop_depth(); 794 increment_loop_depth();
1068 795
1069 __ bind(&body); 796 __ bind(&body);
1070 Visit(stmt->body()); 797 Visit(stmt->body());
1071 798
1072 // Record the position of the do while condition and make sure it is 799 // Record the position of the do while condition and make sure it is
1073 // possible to break on the condition. 800 // possible to break on the condition.
1074 __ bind(loop_statement.continue_label()); 801 __ bind(loop_statement.continue_label());
1075 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 802 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1076 SetExpressionPosition(stmt->cond()); 803
804 // Here is the actual 'while' keyword.
805 SetExpressionAsStatementPosition(stmt->cond());
1077 VisitForControl(stmt->cond(), 806 VisitForControl(stmt->cond(),
1078 &book_keeping, 807 &book_keeping,
1079 loop_statement.break_label(), 808 loop_statement.break_label(),
1080 &book_keeping); 809 &book_keeping);
1081 810
1082 // Check stack before looping. 811 // Check stack before looping.
1083 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 812 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1084 __ bind(&book_keeping); 813 __ bind(&book_keeping);
1085 EmitBackEdgeBookkeeping(stmt, &body); 814 EmitBackEdgeBookkeeping(stmt, &body);
1086 __ jmp(&body); 815 __ jmp(&body);
1087 816
1088 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 817 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1089 __ bind(loop_statement.break_label()); 818 __ bind(loop_statement.break_label());
1090 decrement_loop_depth(); 819 decrement_loop_depth();
1091 } 820 }
1092 821
1093 822
1094 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 823 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1095 Comment cmnt(masm_, "[ WhileStatement"); 824 Comment cmnt(masm_, "[ WhileStatement");
1096 Label loop, body; 825 Label loop, body;
1097 826
1098 Iteration loop_statement(this, stmt); 827 Iteration loop_statement(this, stmt);
1099 increment_loop_depth(); 828 increment_loop_depth();
1100 829
1101 __ bind(&loop); 830 __ bind(&loop);
1102 831
1103 SetExpressionPosition(stmt->cond()); 832 SetExpressionAsStatementPosition(stmt->cond());
1104 VisitForControl(stmt->cond(), 833 VisitForControl(stmt->cond(),
1105 &body, 834 &body,
1106 loop_statement.break_label(), 835 loop_statement.break_label(),
1107 &body); 836 &body);
1108 837
1109 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 838 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1110 __ bind(&body); 839 __ bind(&body);
1111 Visit(stmt->body()); 840 Visit(stmt->body());
1112 841
1113 __ bind(loop_statement.continue_label()); 842 __ bind(loop_statement.continue_label());
1114 843
1115 // Check stack before looping. 844 // Check stack before looping.
1116 EmitBackEdgeBookkeeping(stmt, &loop); 845 EmitBackEdgeBookkeeping(stmt, &loop);
1117 __ jmp(&loop); 846 __ jmp(&loop);
1118 847
1119 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 848 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1120 __ bind(loop_statement.break_label()); 849 __ bind(loop_statement.break_label());
1121 decrement_loop_depth(); 850 decrement_loop_depth();
1122 } 851 }
1123 852
1124 853
1125 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 854 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1126 Comment cmnt(masm_, "[ ForStatement"); 855 Comment cmnt(masm_, "[ ForStatement");
856 // Do not insert break location as we do it below.
857 SetStatementPosition(stmt, SKIP_BREAK);
858
1127 Label test, body; 859 Label test, body;
1128 860
1129 Iteration loop_statement(this, stmt); 861 Iteration loop_statement(this, stmt);
1130 862
1131 // Set statement position for a break slot before entering the for-body.
1132 SetStatementPosition(stmt);
1133
1134 if (stmt->init() != NULL) { 863 if (stmt->init() != NULL) {
1135 SetStatementPosition(stmt->init()); 864 SetStatementPosition(stmt->init());
1136 Visit(stmt->init()); 865 Visit(stmt->init());
1137 } 866 }
1138 867
1139 increment_loop_depth(); 868 increment_loop_depth();
1140 // Emit the test at the bottom of the loop (even if empty). 869 // Emit the test at the bottom of the loop (even if empty).
1141 __ jmp(&test); 870 __ jmp(&test);
1142 871
1143 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 872 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1144 __ bind(&body); 873 __ bind(&body);
1145 Visit(stmt->body()); 874 Visit(stmt->body());
1146 875
1147 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 876 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1148 __ bind(loop_statement.continue_label()); 877 __ bind(loop_statement.continue_label());
1149 if (stmt->next() != NULL) { 878 if (stmt->next() != NULL) {
1150 SetStatementPosition(stmt->next()); 879 SetStatementPosition(stmt->next());
1151 Visit(stmt->next()); 880 Visit(stmt->next());
1152 } 881 }
1153 882
1154 // Emit the statement position here as this is where the for
1155 // statement code starts.
1156 SetStatementPosition(stmt);
1157
1158 // Check stack before looping. 883 // Check stack before looping.
1159 EmitBackEdgeBookkeeping(stmt, &body); 884 EmitBackEdgeBookkeeping(stmt, &body);
1160 885
1161 __ bind(&test); 886 __ bind(&test);
1162 if (stmt->cond() != NULL) { 887 if (stmt->cond() != NULL) {
1163 SetExpressionPosition(stmt->cond()); 888 SetExpressionAsStatementPosition(stmt->cond());
1164 VisitForControl(stmt->cond(), 889 VisitForControl(stmt->cond(),
1165 &body, 890 &body,
1166 loop_statement.break_label(), 891 loop_statement.break_label(),
1167 loop_statement.break_label()); 892 loop_statement.break_label());
1168 } else { 893 } else {
1169 __ jmp(&body); 894 __ jmp(&body);
1170 } 895 }
1171 896
1172 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 897 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1173 __ bind(loop_statement.break_label()); 898 __ bind(loop_statement.break_label());
1174 decrement_loop_depth(); 899 decrement_loop_depth();
1175 } 900 }
1176 901
1177 902
1178 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 903 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1179 Comment cmnt(masm_, "[ ForOfStatement"); 904 Comment cmnt(masm_, "[ ForOfStatement");
1180 SetStatementPosition(stmt);
1181 905
1182 Iteration loop_statement(this, stmt); 906 Iteration loop_statement(this, stmt);
1183 increment_loop_depth(); 907 increment_loop_depth();
1184 908
1185 // var iterator = iterable[Symbol.iterator](); 909 // var iterator = iterable[Symbol.iterator]();
1186 VisitForEffect(stmt->assign_iterator()); 910 VisitForEffect(stmt->assign_iterator());
1187 911
1188 // Loop entry. 912 // Loop entry.
1189 __ bind(loop_statement.continue_label()); 913 __ bind(loop_statement.continue_label());
1190 914
1191 // result = iterator.next() 915 // result = iterator.next()
1192 SetExpressionPosition(stmt->next_result()); 916 SetExpressionAsStatementPosition(stmt->next_result());
1193 VisitForEffect(stmt->next_result()); 917 VisitForEffect(stmt->next_result());
1194 918
1195 // if (result.done) break; 919 // if (result.done) break;
1196 Label result_not_done; 920 Label result_not_done;
1197 VisitForControl(stmt->result_done(), loop_statement.break_label(), 921 VisitForControl(stmt->result_done(), loop_statement.break_label(),
1198 &result_not_done, &result_not_done); 922 &result_not_done, &result_not_done);
1199 __ bind(&result_not_done); 923 __ bind(&result_not_done);
1200 924
1201 // each = result.value 925 // each = result.value
1202 VisitForEffect(stmt->assign_each()); 926 VisitForEffect(stmt->assign_each());
1203 927
1204 // Generate code for the body of the loop. 928 // Generate code for the body of the loop.
1205 Visit(stmt->body()); 929 Visit(stmt->body());
1206 930
1207 // Check stack before looping. 931 // Check stack before looping.
1208 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 932 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1209 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); 933 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
1210 __ jmp(loop_statement.continue_label()); 934 __ jmp(loop_statement.continue_label());
1211 935
1212 // Exit and decrement the loop depth. 936 // Exit and decrement the loop depth.
1213 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 937 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1214 __ bind(loop_statement.break_label()); 938 __ bind(loop_statement.break_label());
1215 decrement_loop_depth(); 939 decrement_loop_depth();
1216 } 940 }
1217 941
1218 942
1219 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 943 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1220 Comment cmnt(masm_, "[ TryCatchStatement"); 944 Comment cmnt(masm_, "[ TryCatchStatement");
1221 SetStatementPosition(stmt); 945 SetStatementPosition(stmt, SKIP_BREAK);
946
1222 // The try block adds a handler to the exception handler chain before 947 // The try block adds a handler to the exception handler chain before
1223 // entering, and removes it again when exiting normally. If an exception 948 // entering, and removes it again when exiting normally. If an exception
1224 // is thrown during execution of the try block, the handler is consumed 949 // is thrown during execution of the try block, the handler is consumed
1225 // and control is passed to the catch block with the exception in the 950 // and control is passed to the catch block with the exception in the
1226 // result register. 951 // result register.
1227 952
1228 Label try_entry, handler_entry, exit; 953 Label try_entry, handler_entry, exit;
1229 __ jmp(&try_entry); 954 __ jmp(&try_entry);
1230 __ bind(&handler_entry); 955 __ bind(&handler_entry);
1231 PrepareForBailoutForId(stmt->HandlerId(), NO_REGISTERS); 956 PrepareForBailoutForId(stmt->HandlerId(), NO_REGISTERS);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 Visit(stmt->try_block()); 989 Visit(stmt->try_block());
1265 } 990 }
1266 ExitTryBlock(handler_index); 991 ExitTryBlock(handler_index);
1267 try_catch_depth_--; 992 try_catch_depth_--;
1268 __ bind(&exit); 993 __ bind(&exit);
1269 } 994 }
1270 995
1271 996
1272 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 997 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1273 Comment cmnt(masm_, "[ TryFinallyStatement"); 998 Comment cmnt(masm_, "[ TryFinallyStatement");
1274 SetStatementPosition(stmt); 999 SetStatementPosition(stmt, SKIP_BREAK);
1000
1275 // Try finally is compiled by setting up a try-handler on the stack while 1001 // Try finally is compiled by setting up a try-handler on the stack while
1276 // executing the try body, and removing it again afterwards. 1002 // executing the try body, and removing it again afterwards.
1277 // 1003 //
1278 // The try-finally construct can enter the finally block in three ways: 1004 // The try-finally construct can enter the finally block in three ways:
1279 // 1. By exiting the try-block normally. This removes the try-handler and 1005 // 1. By exiting the try-block normally. This removes the try-handler and
1280 // calls the finally block code before continuing. 1006 // calls the finally block code before continuing.
1281 // 2. By exiting the try-block with a function-local control flow transfer 1007 // 2. By exiting the try-block with a function-local control flow transfer
1282 // (break/continue/return). The site of the, e.g., break removes the 1008 // (break/continue/return). The site of the, e.g., break removes the
1283 // try handler and calls the finally block code before continuing 1009 // try handler and calls the finally block code before continuing
1284 // its outward control transfer. 1010 // its outward control transfer.
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 int parameters = fun->shared()->internal_formal_parameter_count(); 1206 int parameters = fun->shared()->internal_formal_parameter_count();
1481 shared->set_internal_formal_parameter_count(parameters); 1207 shared->set_internal_formal_parameter_count(parameters);
1482 1208
1483 EmitNewClosure(shared, false); 1209 EmitNewClosure(shared, false);
1484 } 1210 }
1485 1211
1486 1212
1487 void FullCodeGenerator::VisitThrow(Throw* expr) { 1213 void FullCodeGenerator::VisitThrow(Throw* expr) {
1488 Comment cmnt(masm_, "[ Throw"); 1214 Comment cmnt(masm_, "[ Throw");
1489 VisitForStackValue(expr->exception()); 1215 VisitForStackValue(expr->exception());
1490 SetSourcePosition(expr->position()); 1216 SetExpressionPosition(expr);
1491 __ CallRuntime(Runtime::kThrow, 1); 1217 __ CallRuntime(Runtime::kThrow, 1);
1492 // Never returns here. 1218 // Never returns here.
1493 } 1219 }
1494 1220
1495 1221
1496 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) { 1222 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) {
1497 HandlerTableEntry* entry = &handler_table_[handler_index]; 1223 HandlerTableEntry* entry = &handler_table_[handler_index];
1498 entry->range_start = masm()->pc_offset(); 1224 entry->range_start = masm()->pc_offset();
1499 entry->handler_offset = handler->pos(); 1225 entry->handler_offset = handler->pos();
1500 entry->try_catch_depth = try_catch_depth_; 1226 entry->try_catch_depth = try_catch_depth_;
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS); 1434 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS);
1709 codegen_->scope_ = saved_scope_; 1435 codegen_->scope_ = saved_scope_;
1710 } 1436 }
1711 1437
1712 1438
1713 #undef __ 1439 #undef __
1714 1440
1715 1441
1716 } // namespace internal 1442 } // namespace internal
1717 } // namespace v8 1443 } // namespace v8
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/ia32/debug-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698