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

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: minor fixes 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
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 RecordPositions(MacroAssembler* masm, int pos, bool statement = true) {
ulan 2015/07/06 09:24:18 Please use enum instead of bool and avoid implicit
Yang 2015/07/06 10:05:08 Done.
411 if (pos != RelocInfo::kNoPosition) {
412 if (statement) masm->positions_recorder()->RecordStatementPosition(pos);
413 masm->positions_recorder()->RecordPosition(pos);
414 return masm->positions_recorder()->WriteRecordedPositions();
415 }
416 return false;
417 }
418
419
673 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 420 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
674 CodeGenerator::RecordPositions(masm_, fun->start_position()); 421 RecordPositions(masm_, fun->start_position(), false);
675 } 422 }
676 423
677 424
678 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 425 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
679 CodeGenerator::RecordPositions(masm_, fun->end_position() - 1); 426 RecordPositions(masm_, fun->end_position() - 1);
680 } 427 }
681 428
682 429
683 void FullCodeGenerator::SetStatementPosition(Statement* stmt) { 430 void FullCodeGenerator::SetStatementPosition(
684 if (!info_->is_debug()) { 431 Statement* stmt, FullCodeGenerator::InsertBreak insert_break) {
685 CodeGenerator::RecordPositions(masm_, stmt->position()); 432 if (stmt->position() == RelocInfo::kNoPosition) return;
686 } else { 433 bool recorded = RecordPositions(masm_, stmt->position());
687 // Check if the statement will be breakable without adding a debug break 434 if (recorded && insert_break == INSERT_BREAK && info_->is_debug() &&
688 // slot. 435 !stmt->IsDebuggerStatement()) {
689 BreakableStatementChecker checker(info_->isolate(), zone()); 436 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 } 437 }
702 } 438 }
703 439
704 440
441 void FullCodeGenerator::SetExpressionPosition(
442 Expression* expr, FullCodeGenerator::InsertBreak insert_break) {
443 if (expr->position() == RelocInfo::kNoPosition) return;
444 bool recorded = RecordPositions(masm_, expr->position(), false);
445 if (recorded && insert_break == INSERT_BREAK && info_->is_debug()) {
446 DebugCodegen::GenerateSlot(masm_);
447 }
448 }
449
450
451 void FullCodeGenerator::SetExpressionAsStatementPosition(Expression* expr) {
452 if (expr->position() == RelocInfo::kNoPosition) return;
453 bool recorded = RecordPositions(masm_, expr->position());
454 if (recorded && info_->is_debug()) DebugCodegen::GenerateSlot(masm_);
455 }
456
457
705 void FullCodeGenerator::VisitSuperPropertyReference( 458 void FullCodeGenerator::VisitSuperPropertyReference(
706 SuperPropertyReference* super) { 459 SuperPropertyReference* super) {
707 __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); 460 __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
708 } 461 }
709 462
710 463
711 void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) { 464 void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) {
712 __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); 465 __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
713 } 466 }
714 467
715 468
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) { 469 void FullCodeGenerator::EmitGeneratorNext(CallRuntime* expr) {
750 ZoneList<Expression*>* args = expr->arguments(); 470 ZoneList<Expression*>* args = expr->arguments();
751 DCHECK(args->length() == 2); 471 DCHECK(args->length() == 2);
752 EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::NEXT); 472 EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::NEXT);
753 } 473 }
754 474
755 475
756 void FullCodeGenerator::EmitGeneratorThrow(CallRuntime* expr) { 476 void FullCodeGenerator::EmitGeneratorThrow(CallRuntime* expr) {
757 ZoneList<Expression*>* args = expr->arguments(); 477 ZoneList<Expression*>* args = expr->arguments();
758 DCHECK(args->length() == 2); 478 DCHECK(args->length() == 2);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 591
872 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 592 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
873 Token::Value op = expr->op(); 593 Token::Value op = expr->op();
874 Comment cmnt(masm_, "[ ArithmeticExpression"); 594 Comment cmnt(masm_, "[ ArithmeticExpression");
875 Expression* left = expr->left(); 595 Expression* left = expr->left();
876 Expression* right = expr->right(); 596 Expression* right = expr->right();
877 597
878 VisitForStackValue(left); 598 VisitForStackValue(left);
879 VisitForAccumulatorValue(right); 599 VisitForAccumulatorValue(right);
880 600
881 SetSourcePosition(expr->position()); 601 SetExpressionPosition(expr);
882 if (ShouldInlineSmiCase(op)) { 602 if (ShouldInlineSmiCase(op)) {
883 EmitInlineSmiBinaryOp(expr, op, left, right); 603 EmitInlineSmiBinaryOp(expr, op, left, right);
884 } else { 604 } else {
885 EmitBinaryOp(expr, op); 605 EmitBinaryOp(expr, op);
886 } 606 }
887 } 607 }
888 608
889 609
890 void FullCodeGenerator::VisitBlock(Block* stmt) { 610 void FullCodeGenerator::VisitBlock(Block* stmt) {
891 Comment cmnt(masm_, "[ Block"); 611 Comment cmnt(masm_, "[ Block");
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 773
1054 // Pop context. 774 // Pop context.
1055 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 775 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1056 // Update local stack frame context field. 776 // Update local stack frame context field.
1057 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 777 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1058 } 778 }
1059 779
1060 780
1061 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 781 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1062 Comment cmnt(masm_, "[ DoWhileStatement"); 782 Comment cmnt(masm_, "[ DoWhileStatement");
1063 SetStatementPosition(stmt); 783 SetStatementPosition(stmt, SKIP_BREAK);
ulan 2015/07/06 09:24:18 Please add a comment that the break is added below
Yang 2015/07/06 10:05:08 Done.
784
1064 Label body, book_keeping; 785 Label body, book_keeping;
1065 786
1066 Iteration loop_statement(this, stmt); 787 Iteration loop_statement(this, stmt);
1067 increment_loop_depth(); 788 increment_loop_depth();
1068 789
1069 __ bind(&body); 790 __ bind(&body);
1070 Visit(stmt->body()); 791 Visit(stmt->body());
1071 792
1072 // Record the position of the do while condition and make sure it is 793 // Record the position of the do while condition and make sure it is
1073 // possible to break on the condition. 794 // possible to break on the condition.
1074 __ bind(loop_statement.continue_label()); 795 __ bind(loop_statement.continue_label());
1075 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 796 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1076 SetExpressionPosition(stmt->cond()); 797
798 // Here is the actual 'while' keyword.
799 SetExpressionAsStatementPosition(stmt->cond());
1077 VisitForControl(stmt->cond(), 800 VisitForControl(stmt->cond(),
1078 &book_keeping, 801 &book_keeping,
1079 loop_statement.break_label(), 802 loop_statement.break_label(),
1080 &book_keeping); 803 &book_keeping);
1081 804
1082 // Check stack before looping. 805 // Check stack before looping.
1083 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 806 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1084 __ bind(&book_keeping); 807 __ bind(&book_keeping);
1085 EmitBackEdgeBookkeeping(stmt, &body); 808 EmitBackEdgeBookkeeping(stmt, &body);
1086 __ jmp(&body); 809 __ jmp(&body);
1087 810
1088 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 811 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1089 __ bind(loop_statement.break_label()); 812 __ bind(loop_statement.break_label());
1090 decrement_loop_depth(); 813 decrement_loop_depth();
1091 } 814 }
1092 815
1093 816
1094 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 817 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1095 Comment cmnt(masm_, "[ WhileStatement"); 818 Comment cmnt(masm_, "[ WhileStatement");
1096 Label loop, body; 819 Label loop, body;
1097 820
1098 Iteration loop_statement(this, stmt); 821 Iteration loop_statement(this, stmt);
1099 increment_loop_depth(); 822 increment_loop_depth();
1100 823
1101 __ bind(&loop); 824 __ bind(&loop);
1102 825
1103 SetExpressionPosition(stmt->cond()); 826 SetExpressionAsStatementPosition(stmt->cond());
1104 VisitForControl(stmt->cond(), 827 VisitForControl(stmt->cond(),
1105 &body, 828 &body,
1106 loop_statement.break_label(), 829 loop_statement.break_label(),
1107 &body); 830 &body);
1108 831
1109 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 832 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1110 __ bind(&body); 833 __ bind(&body);
1111 Visit(stmt->body()); 834 Visit(stmt->body());
1112 835
1113 __ bind(loop_statement.continue_label()); 836 __ bind(loop_statement.continue_label());
1114 837
1115 // Check stack before looping. 838 // Check stack before looping.
1116 EmitBackEdgeBookkeeping(stmt, &loop); 839 EmitBackEdgeBookkeeping(stmt, &loop);
1117 __ jmp(&loop); 840 __ jmp(&loop);
1118 841
1119 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 842 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1120 __ bind(loop_statement.break_label()); 843 __ bind(loop_statement.break_label());
1121 decrement_loop_depth(); 844 decrement_loop_depth();
1122 } 845 }
1123 846
1124 847
1125 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 848 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1126 Comment cmnt(masm_, "[ ForStatement"); 849 Comment cmnt(masm_, "[ ForStatement");
850 SetStatementPosition(stmt, SKIP_BREAK);
ulan 2015/07/06 09:24:18 Please add a comment that the break is added below
Yang 2015/07/06 10:05:08 Done.
851
1127 Label test, body; 852 Label test, body;
1128 853
1129 Iteration loop_statement(this, stmt); 854 Iteration loop_statement(this, stmt);
1130 855
1131 // Set statement position for a break slot before entering the for-body.
1132 SetStatementPosition(stmt);
1133
1134 if (stmt->init() != NULL) { 856 if (stmt->init() != NULL) {
1135 SetStatementPosition(stmt->init()); 857 SetStatementPosition(stmt->init());
1136 Visit(stmt->init()); 858 Visit(stmt->init());
1137 } 859 }
1138 860
1139 increment_loop_depth(); 861 increment_loop_depth();
1140 // Emit the test at the bottom of the loop (even if empty). 862 // Emit the test at the bottom of the loop (even if empty).
1141 __ jmp(&test); 863 __ jmp(&test);
1142 864
1143 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 865 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1144 __ bind(&body); 866 __ bind(&body);
1145 Visit(stmt->body()); 867 Visit(stmt->body());
1146 868
1147 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 869 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1148 __ bind(loop_statement.continue_label()); 870 __ bind(loop_statement.continue_label());
1149 if (stmt->next() != NULL) { 871 if (stmt->next() != NULL) {
1150 SetStatementPosition(stmt->next()); 872 SetStatementPosition(stmt->next());
1151 Visit(stmt->next()); 873 Visit(stmt->next());
1152 } 874 }
1153 875
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. 876 // Check stack before looping.
1159 EmitBackEdgeBookkeeping(stmt, &body); 877 EmitBackEdgeBookkeeping(stmt, &body);
1160 878
1161 __ bind(&test); 879 __ bind(&test);
1162 if (stmt->cond() != NULL) { 880 if (stmt->cond() != NULL) {
1163 SetExpressionPosition(stmt->cond()); 881 SetExpressionAsStatementPosition(stmt->cond());
1164 VisitForControl(stmt->cond(), 882 VisitForControl(stmt->cond(),
1165 &body, 883 &body,
1166 loop_statement.break_label(), 884 loop_statement.break_label(),
1167 loop_statement.break_label()); 885 loop_statement.break_label());
1168 } else { 886 } else {
1169 __ jmp(&body); 887 __ jmp(&body);
1170 } 888 }
1171 889
1172 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 890 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1173 __ bind(loop_statement.break_label()); 891 __ bind(loop_statement.break_label());
1174 decrement_loop_depth(); 892 decrement_loop_depth();
1175 } 893 }
1176 894
1177 895
1178 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 896 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1179 Comment cmnt(masm_, "[ ForOfStatement"); 897 Comment cmnt(masm_, "[ ForOfStatement");
1180 SetStatementPosition(stmt);
1181 898
1182 Iteration loop_statement(this, stmt); 899 Iteration loop_statement(this, stmt);
1183 increment_loop_depth(); 900 increment_loop_depth();
1184 901
1185 // var iterator = iterable[Symbol.iterator](); 902 // var iterator = iterable[Symbol.iterator]();
1186 VisitForEffect(stmt->assign_iterator()); 903 VisitForEffect(stmt->assign_iterator());
1187 904
1188 // Loop entry. 905 // Loop entry.
1189 __ bind(loop_statement.continue_label()); 906 __ bind(loop_statement.continue_label());
1190 907
1191 // result = iterator.next() 908 // result = iterator.next()
1192 SetExpressionPosition(stmt->next_result()); 909 SetExpressionAsStatementPosition(stmt->next_result());
1193 VisitForEffect(stmt->next_result()); 910 VisitForEffect(stmt->next_result());
1194 911
1195 // if (result.done) break; 912 // if (result.done) break;
1196 Label result_not_done; 913 Label result_not_done;
1197 VisitForControl(stmt->result_done(), loop_statement.break_label(), 914 VisitForControl(stmt->result_done(), loop_statement.break_label(),
1198 &result_not_done, &result_not_done); 915 &result_not_done, &result_not_done);
1199 __ bind(&result_not_done); 916 __ bind(&result_not_done);
1200 917
1201 // each = result.value 918 // each = result.value
1202 VisitForEffect(stmt->assign_each()); 919 VisitForEffect(stmt->assign_each());
1203 920
1204 // Generate code for the body of the loop. 921 // Generate code for the body of the loop.
1205 Visit(stmt->body()); 922 Visit(stmt->body());
1206 923
1207 // Check stack before looping. 924 // Check stack before looping.
1208 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 925 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1209 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); 926 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
1210 __ jmp(loop_statement.continue_label()); 927 __ jmp(loop_statement.continue_label());
1211 928
1212 // Exit and decrement the loop depth. 929 // Exit and decrement the loop depth.
1213 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 930 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1214 __ bind(loop_statement.break_label()); 931 __ bind(loop_statement.break_label());
1215 decrement_loop_depth(); 932 decrement_loop_depth();
1216 } 933 }
1217 934
1218 935
1219 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 936 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1220 Comment cmnt(masm_, "[ TryCatchStatement"); 937 Comment cmnt(masm_, "[ TryCatchStatement");
1221 SetStatementPosition(stmt); 938 SetStatementPosition(stmt, SKIP_BREAK);
939
1222 // The try block adds a handler to the exception handler chain before 940 // The try block adds a handler to the exception handler chain before
1223 // entering, and removes it again when exiting normally. If an exception 941 // entering, and removes it again when exiting normally. If an exception
1224 // is thrown during execution of the try block, the handler is consumed 942 // 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 943 // and control is passed to the catch block with the exception in the
1226 // result register. 944 // result register.
1227 945
1228 Label try_entry, handler_entry, exit; 946 Label try_entry, handler_entry, exit;
1229 __ jmp(&try_entry); 947 __ jmp(&try_entry);
1230 __ bind(&handler_entry); 948 __ bind(&handler_entry);
1231 PrepareForBailoutForId(stmt->HandlerId(), NO_REGISTERS); 949 PrepareForBailoutForId(stmt->HandlerId(), NO_REGISTERS);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 Visit(stmt->try_block()); 982 Visit(stmt->try_block());
1265 } 983 }
1266 ExitTryBlock(handler_index); 984 ExitTryBlock(handler_index);
1267 try_catch_depth_--; 985 try_catch_depth_--;
1268 __ bind(&exit); 986 __ bind(&exit);
1269 } 987 }
1270 988
1271 989
1272 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 990 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1273 Comment cmnt(masm_, "[ TryFinallyStatement"); 991 Comment cmnt(masm_, "[ TryFinallyStatement");
1274 SetStatementPosition(stmt); 992 SetStatementPosition(stmt, SKIP_BREAK);
993
1275 // Try finally is compiled by setting up a try-handler on the stack while 994 // Try finally is compiled by setting up a try-handler on the stack while
1276 // executing the try body, and removing it again afterwards. 995 // executing the try body, and removing it again afterwards.
1277 // 996 //
1278 // The try-finally construct can enter the finally block in three ways: 997 // 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 998 // 1. By exiting the try-block normally. This removes the try-handler and
1280 // calls the finally block code before continuing. 999 // calls the finally block code before continuing.
1281 // 2. By exiting the try-block with a function-local control flow transfer 1000 // 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 1001 // (break/continue/return). The site of the, e.g., break removes the
1283 // try handler and calls the finally block code before continuing 1002 // try handler and calls the finally block code before continuing
1284 // its outward control transfer. 1003 // 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(); 1199 int parameters = fun->shared()->internal_formal_parameter_count();
1481 shared->set_internal_formal_parameter_count(parameters); 1200 shared->set_internal_formal_parameter_count(parameters);
1482 1201
1483 EmitNewClosure(shared, false); 1202 EmitNewClosure(shared, false);
1484 } 1203 }
1485 1204
1486 1205
1487 void FullCodeGenerator::VisitThrow(Throw* expr) { 1206 void FullCodeGenerator::VisitThrow(Throw* expr) {
1488 Comment cmnt(masm_, "[ Throw"); 1207 Comment cmnt(masm_, "[ Throw");
1489 VisitForStackValue(expr->exception()); 1208 VisitForStackValue(expr->exception());
1490 SetSourcePosition(expr->position()); 1209 SetExpressionPosition(expr);
1491 __ CallRuntime(Runtime::kThrow, 1); 1210 __ CallRuntime(Runtime::kThrow, 1);
1492 // Never returns here. 1211 // Never returns here.
1493 } 1212 }
1494 1213
1495 1214
1496 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) { 1215 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) {
1497 HandlerTableEntry* entry = &handler_table_[handler_index]; 1216 HandlerTableEntry* entry = &handler_table_[handler_index];
1498 entry->range_start = masm()->pc_offset(); 1217 entry->range_start = masm()->pc_offset();
1499 entry->handler_offset = handler->pos(); 1218 entry->handler_offset = handler->pos();
1500 entry->try_catch_depth = try_catch_depth_; 1219 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); 1427 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS);
1709 codegen_->scope_ = saved_scope_; 1428 codegen_->scope_ = saved_scope_;
1710 } 1429 }
1711 1430
1712 1431
1713 #undef __ 1432 #undef __
1714 1433
1715 1434
1716 } // namespace internal 1435 } // namespace internal
1717 } // namespace v8 1436 } // namespace v8
OLDNEW
« src/full-codegen.h ('K') | « 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