OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |