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

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

Issue 2693002: More precise break points and stepping when debugging... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/full-codegen.h ('k') | src/ia32/assembler-ia32.h » ('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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 432
433 433
434 void FullCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) { 434 void FullCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
435 // Supported. 435 // Supported.
436 } 436 }
437 437
438 #undef BAILOUT 438 #undef BAILOUT
439 #undef CHECK_BAILOUT 439 #undef CHECK_BAILOUT
440 440
441 441
442 void BreakableStatementChecker::Check(Statement* stmt) {
443 Visit(stmt);
444 }
445
446
447 void BreakableStatementChecker::Check(Expression* expr) {
448 Visit(expr);
449 }
450
451
452 void BreakableStatementChecker::VisitDeclaration(Declaration* decl) {
453 }
454
455
456 void BreakableStatementChecker::VisitBlock(Block* stmt) {
457 }
458
459
460 void BreakableStatementChecker::VisitExpressionStatement(
461 ExpressionStatement* stmt) {
462 // Check if expression is breakable.
463 Visit(stmt->expression());
464 }
465
466
467 void BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) {
468 }
469
470
471 void BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) {
472 // If the condition is breakable the if statement is breakable.
473 Visit(stmt->condition());
474 }
475
476
477 void BreakableStatementChecker::VisitContinueStatement(
478 ContinueStatement* stmt) {
479 }
480
481
482 void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) {
483 }
484
485
486 void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) {
487 // Return is breakable if the expression is.
488 Visit(stmt->expression());
489 }
490
491
492 void BreakableStatementChecker::VisitWithEnterStatement(
493 WithEnterStatement* stmt) {
494 Visit(stmt->expression());
495 }
496
497
498 void BreakableStatementChecker::VisitWithExitStatement(
499 WithExitStatement* stmt) {
500 }
501
502
503 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
504 // Switch statements breakable if the tag expression is.
505 Visit(stmt->tag());
506 }
507
508
509 void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
510 // Mark do while as breakable to avoid adding a break slot in front of it.
511 is_breakable_ = true;
512 }
513
514
515 void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) {
516 // Mark while statements breakable if the condition expression is.
517 Visit(stmt->cond());
518 }
519
520
521 void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
522 // Mark for statements breakable if the condition expression is.
523 if (stmt->cond() != NULL) {
524 Visit(stmt->cond());
525 }
526 }
527
528
529 void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
530 // Mark for in statements breakable if the enumerable expression is.
531 Visit(stmt->enumerable());
532 }
533
534
535 void BreakableStatementChecker::VisitTryCatchStatement(
536 TryCatchStatement* stmt) {
537 // Mark try catch as breakable to avoid adding a break slot in front of it.
538 is_breakable_ = true;
539 }
540
541
542 void BreakableStatementChecker::VisitTryFinallyStatement(
543 TryFinallyStatement* stmt) {
544 // Mark try finally as breakable to avoid adding a break slot in front of it.
545 is_breakable_ = true;
546 }
547
548
549 void BreakableStatementChecker::VisitDebuggerStatement(
550 DebuggerStatement* stmt) {
551 // The debugger statement is breakable.
552 is_breakable_ = true;
553 }
554
555
556 void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
557 }
558
559
560 void BreakableStatementChecker::VisitSharedFunctionInfoLiteral(
561 SharedFunctionInfoLiteral* expr) {
562 }
563
564
565 void BreakableStatementChecker::VisitConditional(Conditional* expr) {
566 }
567
568
569 void BreakableStatementChecker::VisitSlot(Slot* expr) {
570 }
571
572
573 void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) {
574 }
575
576
577 void BreakableStatementChecker::VisitLiteral(Literal* expr) {
578 }
579
580
581 void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
582 }
583
584
585 void BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) {
586 }
587
588
589 void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) {
590 }
591
592
593 void BreakableStatementChecker::VisitCatchExtensionObject(
594 CatchExtensionObject* expr) {
595 }
596
597
598 void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
599 // If assigning to a property (including a global property) the assignment is
600 // breakable.
601 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
602 Property* prop = expr->target()->AsProperty();
603 if (prop != NULL || (var != NULL && var->is_global())) {
604 is_breakable_ = true;
605 return;
606 }
607
608 // Otherwise the assignment is breakable if the assigned value is.
609 Visit(expr->value());
610 }
611
612
613 void BreakableStatementChecker::VisitThrow(Throw* expr) {
614 // Throw is breakable if the expression is.
615 Visit(expr->exception());
616 }
617
618
619 void BreakableStatementChecker::VisitProperty(Property* expr) {
620 // Property load is breakable.
621 is_breakable_ = true;
622 }
623
624
625 void BreakableStatementChecker::VisitCall(Call* expr) {
626 // Function calls both through IC and call stub are breakable.
627 is_breakable_ = true;
628 }
629
630
631 void BreakableStatementChecker::VisitCallNew(CallNew* expr) {
632 // Function calls through new are breakable.
633 is_breakable_ = true;
634 }
635
636
637 void BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) {
638 }
639
640
641 void BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) {
642 Visit(expr->expression());
643 }
644
645
646 void BreakableStatementChecker::VisitCountOperation(CountOperation* expr) {
647 Visit(expr->expression());
648 }
649
650
651 void BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) {
652 Visit(expr->left());
653 Visit(expr->right());
654 }
655
656
657 void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) {
658 Visit(expr->left());
659 Visit(expr->right());
660 }
661
662
663 void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
664 }
665
666
442 #define __ ACCESS_MASM(masm()) 667 #define __ ACCESS_MASM(masm())
443 668
444 Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) { 669 Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) {
445 Handle<Script> script = info->script(); 670 Handle<Script> script = info->script();
446 if (!script->IsUndefined() && !script->source()->IsUndefined()) { 671 if (!script->IsUndefined() && !script->source()->IsUndefined()) {
447 int len = String::cast(script->source())->length(); 672 int len = String::cast(script->source())->length();
448 Counters::total_full_codegen_source_size.Increment(len); 673 Counters::total_full_codegen_source_size.Increment(len);
449 } 674 }
450 CodeGenerator::MakeCodePrologue(info); 675 CodeGenerator::MakeCodePrologue(info);
451 const int kInitialBufferSize = 4 * KB; 676 const int kInitialBufferSize = 4 * KB;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 770
546 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 771 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
547 if (FLAG_debug_info) { 772 if (FLAG_debug_info) {
548 CodeGenerator::RecordPositions(masm_, fun->end_position()); 773 CodeGenerator::RecordPositions(masm_, fun->end_position());
549 } 774 }
550 } 775 }
551 776
552 777
553 void FullCodeGenerator::SetStatementPosition(Statement* stmt) { 778 void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
554 if (FLAG_debug_info) { 779 if (FLAG_debug_info) {
780 #ifdef ENABLE_DEBUGGER_SUPPORT
781 if (!Debugger::IsDebuggerActive()) {
782 CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
783 } else {
784 // Check if the statement will be breakable without adding a debug break
785 // slot.
786 BreakableStatementChecker checker;
787 checker.Check(stmt);
788 // Record the statement position right here if the statement is not
789 // breakable. For breakable statements the actual recording of the
790 // position will be postponed to the breakable code (typically an IC).
791 bool position_recorded = CodeGenerator::RecordPositions(
792 masm_, stmt->statement_pos(), !checker.is_breakable());
793 // If the position recording did record a new position generate a debug
794 // break slot to make the statement breakable.
795 if (position_recorded) {
796 Debug::GenerateSlot(masm_);
797 }
798 }
799 #else
555 CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 800 CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
801 #endif
802 }
803 }
804
805
806 void FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) {
807 if (FLAG_debug_info) {
808 #ifdef ENABLE_DEBUGGER_SUPPORT
809 if (!Debugger::IsDebuggerActive()) {
810 CodeGenerator::RecordPositions(masm_, pos);
811 } else {
812 // Check if the expression will be breakable without adding a debug break
813 // slot.
814 BreakableStatementChecker checker;
815 checker.Check(expr);
816 // Record a statement position right here if the expression is not
817 // breakable. For breakable expressions the actual recording of the
818 // position will be postponed to the breakable code (typically an IC).
819 // NOTE this will record a statement position for something which might
820 // not be a statement. As stepping in the debugger will only stop at
821 // statement positions this is used for e.g. the condition expression of
822 // a do while loop.
823 bool position_recorded = CodeGenerator::RecordPositions(
824 masm_, pos, !checker.is_breakable());
825 // If the position recording did record a new position generate a debug
826 // break slot to make the statement breakable.
827 if (position_recorded) {
828 Debug::GenerateSlot(masm_);
829 }
830 }
831 #else
832 CodeGenerator::RecordPositions(masm_, pos);
833 #endif
556 } 834 }
557 } 835 }
558 836
559 837
560 void FullCodeGenerator::SetStatementPosition(int pos) { 838 void FullCodeGenerator::SetStatementPosition(int pos) {
561 if (FLAG_debug_info) { 839 if (FLAG_debug_info) {
562 CodeGenerator::RecordPositions(masm_, pos); 840 CodeGenerator::RecordPositions(masm_, pos);
563 } 841 }
564 } 842 }
565 843
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 increment_loop_depth(); 1119 increment_loop_depth();
842 1120
843 __ bind(&body); 1121 __ bind(&body);
844 Visit(stmt->body()); 1122 Visit(stmt->body());
845 1123
846 // Check stack before looping. 1124 // Check stack before looping.
847 __ StackLimitCheck(&stack_limit_hit); 1125 __ StackLimitCheck(&stack_limit_hit);
848 __ bind(&stack_check_success); 1126 __ bind(&stack_check_success);
849 1127
850 __ bind(loop_statement.continue_target()); 1128 __ bind(loop_statement.continue_target());
851 SetStatementPosition(stmt->condition_position()); 1129
1130 // Record the position of the do while condition and make sure it is possible
1131 // to break on the condition.
1132 SetExpressionPosition(stmt->cond(), stmt->condition_position());
1133
852 VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 1134 VisitForControl(stmt->cond(), &body, loop_statement.break_target());
853 1135
854 __ bind(&stack_limit_hit); 1136 __ bind(&stack_limit_hit);
855 StackCheckStub stack_stub; 1137 StackCheckStub stack_stub;
856 __ CallStub(&stack_stub); 1138 __ CallStub(&stack_stub);
857 __ jmp(&stack_check_success); 1139 __ jmp(&stack_check_success);
858 1140
859 __ bind(loop_statement.break_target()); 1141 __ bind(loop_statement.break_target());
860 1142
861 decrement_loop_depth(); 1143 decrement_loop_depth();
862 } 1144 }
863 1145
864 1146
865 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1147 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
866 Comment cmnt(masm_, "[ WhileStatement"); 1148 Comment cmnt(masm_, "[ WhileStatement");
867 SetStatementPosition(stmt);
868 Label body, stack_limit_hit, stack_check_success; 1149 Label body, stack_limit_hit, stack_check_success;
869 1150
870 Iteration loop_statement(this, stmt); 1151 Iteration loop_statement(this, stmt);
871 increment_loop_depth(); 1152 increment_loop_depth();
872 1153
873 // Emit the test at the bottom of the loop. 1154 // Emit the test at the bottom of the loop.
874 __ jmp(loop_statement.continue_target()); 1155 __ jmp(loop_statement.continue_target());
875 1156
876 __ bind(&body); 1157 __ bind(&body);
877 Visit(stmt->body()); 1158 Visit(stmt->body());
878 1159
879 __ bind(loop_statement.continue_target()); 1160 __ bind(loop_statement.continue_target());
1161 // Emit the statement position here as this is where the while statement code
1162 // starts.
1163 SetStatementPosition(stmt);
880 1164
881 // Check stack before looping. 1165 // Check stack before looping.
882 __ StackLimitCheck(&stack_limit_hit); 1166 __ StackLimitCheck(&stack_limit_hit);
883 __ bind(&stack_check_success); 1167 __ bind(&stack_check_success);
884 1168
885 VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 1169 VisitForControl(stmt->cond(), &body, loop_statement.break_target());
886 1170
887 __ bind(&stack_limit_hit); 1171 __ bind(&stack_limit_hit);
888 StackCheckStub stack_stub; 1172 StackCheckStub stack_stub;
889 __ CallStub(&stack_stub); 1173 __ CallStub(&stack_stub);
890 __ jmp(&stack_check_success); 1174 __ jmp(&stack_check_success);
891 1175
892 __ bind(loop_statement.break_target()); 1176 __ bind(loop_statement.break_target());
893 decrement_loop_depth(); 1177 decrement_loop_depth();
894 } 1178 }
895 1179
896 1180
897 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1181 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
898 Comment cmnt(masm_, "[ ForStatement"); 1182 Comment cmnt(masm_, "[ ForStatement");
899 SetStatementPosition(stmt);
900 Label test, body, stack_limit_hit, stack_check_success; 1183 Label test, body, stack_limit_hit, stack_check_success;
901 1184
902 Iteration loop_statement(this, stmt); 1185 Iteration loop_statement(this, stmt);
903 if (stmt->init() != NULL) { 1186 if (stmt->init() != NULL) {
904 Visit(stmt->init()); 1187 Visit(stmt->init());
905 } 1188 }
906 1189
907 increment_loop_depth(); 1190 increment_loop_depth();
908 // Emit the test at the bottom of the loop (even if empty). 1191 // Emit the test at the bottom of the loop (even if empty).
909 __ jmp(&test); 1192 __ jmp(&test);
910 1193
911 __ bind(&body); 1194 __ bind(&body);
912 Visit(stmt->body()); 1195 Visit(stmt->body());
913 1196
914 __ bind(loop_statement.continue_target()); 1197 __ bind(loop_statement.continue_target());
915 1198
916 SetStatementPosition(stmt); 1199 SetStatementPosition(stmt);
917 if (stmt->next() != NULL) { 1200 if (stmt->next() != NULL) {
918 Visit(stmt->next()); 1201 Visit(stmt->next());
919 } 1202 }
920 1203
921 __ bind(&test); 1204 __ bind(&test);
1205 // Emit the statement position here as this is where the for statement code
1206 // starts.
1207 SetStatementPosition(stmt);
922 1208
923 // Check stack before looping. 1209 // Check stack before looping.
924 __ StackLimitCheck(&stack_limit_hit); 1210 __ StackLimitCheck(&stack_limit_hit);
925 __ bind(&stack_check_success); 1211 __ bind(&stack_check_success);
926 1212
927 if (stmt->cond() != NULL) { 1213 if (stmt->cond() != NULL) {
928 VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 1214 VisitForControl(stmt->cond(), &body, loop_statement.break_target());
929 } else { 1215 } else {
930 __ jmp(&body); 1216 __ jmp(&body);
931 } 1217 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 #endif 1343 #endif
1058 } 1344 }
1059 1345
1060 1346
1061 void FullCodeGenerator::VisitConditional(Conditional* expr) { 1347 void FullCodeGenerator::VisitConditional(Conditional* expr) {
1062 Comment cmnt(masm_, "[ Conditional"); 1348 Comment cmnt(masm_, "[ Conditional");
1063 Label true_case, false_case, done; 1349 Label true_case, false_case, done;
1064 VisitForControl(expr->condition(), &true_case, &false_case); 1350 VisitForControl(expr->condition(), &true_case, &false_case);
1065 1351
1066 __ bind(&true_case); 1352 __ bind(&true_case);
1353 SetExpressionPosition(expr->then_expression(),
1354 expr->then_expression_position());
1067 Visit(expr->then_expression()); 1355 Visit(expr->then_expression());
1068 // If control flow falls through Visit, jump to done. 1356 // If control flow falls through Visit, jump to done.
1069 if (context_ == Expression::kEffect || context_ == Expression::kValue) { 1357 if (context_ == Expression::kEffect || context_ == Expression::kValue) {
1070 __ jmp(&done); 1358 __ jmp(&done);
1071 } 1359 }
1072 1360
1073 __ bind(&false_case); 1361 __ bind(&false_case);
1362 SetExpressionPosition(expr->else_expression(),
1363 expr->else_expression_position());
1074 Visit(expr->else_expression()); 1364 Visit(expr->else_expression());
1075 // If control flow falls through Visit, merge it with true case here. 1365 // If control flow falls through Visit, merge it with true case here.
1076 if (context_ == Expression::kEffect || context_ == Expression::kValue) { 1366 if (context_ == Expression::kEffect || context_ == Expression::kValue) {
1077 __ bind(&done); 1367 __ bind(&done);
1078 } 1368 }
1079 } 1369 }
1080 1370
1081 1371
1082 void FullCodeGenerator::VisitSlot(Slot* expr) { 1372 void FullCodeGenerator::VisitSlot(Slot* expr) {
1083 // Slots do not appear directly in the AST. 1373 // Slots do not appear directly in the AST.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 // The macros used here must preserve the result register. 1432 // The macros used here must preserve the result register.
1143 __ Drop(stack_depth); 1433 __ Drop(stack_depth);
1144 __ PopTryHandler(); 1434 __ PopTryHandler();
1145 return 0; 1435 return 0;
1146 } 1436 }
1147 1437
1148 #undef __ 1438 #undef __
1149 1439
1150 1440
1151 } } // namespace v8::internal 1441 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698