OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 // tests. | 642 // tests. |
643 char last_script_name_hit[80]; | 643 char last_script_name_hit[80]; |
644 char last_script_data_hit[80]; | 644 char last_script_data_hit[80]; |
645 | 645 |
646 // Global variables to store the last source position - used by some tests. | 646 // Global variables to store the last source position - used by some tests. |
647 int last_source_line = -1; | 647 int last_source_line = -1; |
648 int last_source_column = -1; | 648 int last_source_column = -1; |
649 | 649 |
650 // Debug event handler which counts the break points which have been hit. | 650 // Debug event handler which counts the break points which have been hit. |
651 int break_point_hit_count = 0; | 651 int break_point_hit_count = 0; |
| 652 int break_point_hit_count_deoptimize = 0; |
652 static void DebugEventBreakPointHitCount(v8::DebugEvent event, | 653 static void DebugEventBreakPointHitCount(v8::DebugEvent event, |
653 v8::Handle<v8::Object> exec_state, | 654 v8::Handle<v8::Object> exec_state, |
654 v8::Handle<v8::Object> event_data, | 655 v8::Handle<v8::Object> event_data, |
655 v8::Handle<v8::Value> data) { | 656 v8::Handle<v8::Value> data) { |
656 Debug* debug = v8::internal::Isolate::Current()->debug(); | 657 Debug* debug = v8::internal::Isolate::Current()->debug(); |
657 // When hitting a debug event listener there must be a break set. | 658 // When hitting a debug event listener there must be a break set. |
658 CHECK_NE(debug->break_id(), 0); | 659 CHECK_NE(debug->break_id(), 0); |
659 | 660 |
660 // Count the number of breaks. | 661 // Count the number of breaks. |
661 if (event == v8::Break) { | 662 if (event == v8::Break) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 argc, argv); | 719 argc, argv); |
719 if (result->IsUndefined()) { | 720 if (result->IsUndefined()) { |
720 last_script_data_hit[0] = '\0'; | 721 last_script_data_hit[0] = '\0'; |
721 } else { | 722 } else { |
722 result = result->ToString(); | 723 result = result->ToString(); |
723 CHECK(result->IsString()); | 724 CHECK(result->IsString()); |
724 v8::Handle<v8::String> script_data(result->ToString()); | 725 v8::Handle<v8::String> script_data(result->ToString()); |
725 script_data->WriteAscii(last_script_data_hit); | 726 script_data->WriteAscii(last_script_data_hit); |
726 } | 727 } |
727 } | 728 } |
| 729 |
| 730 // Perform a full deoptimization when the specified number of |
| 731 // breaks have been hit. |
| 732 if (break_point_hit_count == break_point_hit_count_deoptimize) { |
| 733 i::Deoptimizer::DeoptimizeAll(); |
| 734 } |
728 } else if (event == v8::AfterCompile && !compiled_script_data.IsEmpty()) { | 735 } else if (event == v8::AfterCompile && !compiled_script_data.IsEmpty()) { |
729 const int argc = 1; | 736 const int argc = 1; |
730 v8::Handle<v8::Value> argv[argc] = { event_data }; | 737 v8::Handle<v8::Value> argv[argc] = { event_data }; |
731 v8::Handle<v8::Value> result = compiled_script_data->Call(exec_state, | 738 v8::Handle<v8::Value> result = compiled_script_data->Call(exec_state, |
732 argc, argv); | 739 argc, argv); |
733 if (result->IsUndefined()) { | 740 if (result->IsUndefined()) { |
734 last_script_data_hit[0] = '\0'; | 741 last_script_data_hit[0] = '\0'; |
735 } else { | 742 } else { |
736 result = result->ToString(); | 743 result = result->ToString(); |
737 CHECK(result->IsString()); | 744 CHECK(result->IsString()); |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 v8::Handle<v8::Value> data) { | 983 v8::Handle<v8::Value> data) { |
977 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); | 984 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
978 // When hitting a debug event listener there must be a break set. | 985 // When hitting a debug event listener there must be a break set. |
979 CHECK_NE(debug->break_id(), 0); | 986 CHECK_NE(debug->break_id(), 0); |
980 | 987 |
981 if (event == v8::Break) { | 988 if (event == v8::Break) { |
982 if (break_point_hit_count < max_break_point_hit_count) { | 989 if (break_point_hit_count < max_break_point_hit_count) { |
983 // Count the number of breaks. | 990 // Count the number of breaks. |
984 break_point_hit_count++; | 991 break_point_hit_count++; |
985 | 992 |
| 993 // Collect the JavsScript stack height if the function frame_count is |
| 994 // compiled. |
| 995 if (!frame_count.IsEmpty()) { |
| 996 static const int kArgc = 1; |
| 997 v8::Handle<v8::Value> argv[kArgc] = { exec_state }; |
| 998 // Using exec_state as receiver is just to have a receiver. |
| 999 v8::Handle<v8::Value> result = |
| 1000 frame_count->Call(exec_state, kArgc, argv); |
| 1001 last_js_stack_height = result->Int32Value(); |
| 1002 } |
| 1003 |
986 // Set the break flag again to come back here as soon as possible. | 1004 // Set the break flag again to come back here as soon as possible. |
987 v8::Debug::DebugBreak(); | 1005 v8::Debug::DebugBreak(); |
| 1006 |
988 } else if (terminate_after_max_break_point_hit) { | 1007 } else if (terminate_after_max_break_point_hit) { |
989 // Terminate execution after the last break if requested. | 1008 // Terminate execution after the last break if requested. |
990 v8::V8::TerminateExecution(); | 1009 v8::V8::TerminateExecution(); |
991 } | 1010 } |
| 1011 |
| 1012 // Perform a full deoptimization when the specified number of |
| 1013 // breaks have been hit. |
| 1014 if (break_point_hit_count == break_point_hit_count_deoptimize) { |
| 1015 i::Deoptimizer::DeoptimizeAll(); |
| 1016 } |
992 } | 1017 } |
993 } | 1018 } |
994 | 1019 |
995 | 1020 |
996 // --- M e s s a g e C a l l b a c k | 1021 // --- M e s s a g e C a l l b a c k |
997 | 1022 |
998 | 1023 |
999 // Message callback which counts the number of messages. | 1024 // Message callback which counts the number of messages. |
1000 int message_callback_count = 0; | 1025 int message_callback_count = 0; |
1001 | 1026 |
(...skipping 6186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7188 "loop(0);"; | 7213 "loop(0);"; |
7189 v8::Script::Compile(v8::String::New(src))->Run(); | 7214 v8::Script::Compile(v8::String::New(src))->Run(); |
7190 } | 7215 } |
7191 | 7216 |
7192 | 7217 |
7193 // Test that setting the terminate execution flag during debug break processing. | 7218 // Test that setting the terminate execution flag during debug break processing. |
7194 static void TestDebugBreakInLoop(const char* loop_head, | 7219 static void TestDebugBreakInLoop(const char* loop_head, |
7195 const char** loop_bodies, | 7220 const char** loop_bodies, |
7196 const char* loop_tail) { | 7221 const char* loop_tail) { |
7197 // Receive 100 breaks for each test and then terminate JavaScript execution. | 7222 // Receive 100 breaks for each test and then terminate JavaScript execution. |
7198 static int count = 0; | 7223 static const int kBreaksPerTest = 100; |
7199 | 7224 |
7200 for (int i = 0; loop_bodies[i] != NULL; i++) { | 7225 for (int i = 0; i < 1 && loop_bodies[i] != NULL; i++) { |
7201 count++; | 7226 // Perform a lazy deoptimization after various numbers of breaks |
7202 max_break_point_hit_count = count * 100; | 7227 // have been hit. |
7203 terminate_after_max_break_point_hit = true; | 7228 for (int j = 0; j < 10; j++) { |
| 7229 break_point_hit_count_deoptimize = j; |
| 7230 if (j == 10) { |
| 7231 break_point_hit_count_deoptimize = kBreaksPerTest; |
| 7232 } |
7204 | 7233 |
7205 EmbeddedVector<char, 1024> buffer; | 7234 break_point_hit_count = 0; |
7206 OS::SNPrintF(buffer, | 7235 max_break_point_hit_count = kBreaksPerTest; |
7207 "function f() {%s%s%s}", | 7236 terminate_after_max_break_point_hit = true; |
7208 loop_head, loop_bodies[i], loop_tail); | |
7209 | 7237 |
7210 // Function with infinite loop. | 7238 EmbeddedVector<char, 1024> buffer; |
7211 CompileRun(buffer.start()); | 7239 OS::SNPrintF(buffer, |
| 7240 "function f() {%s%s%s}", |
| 7241 loop_head, loop_bodies[i], loop_tail); |
7212 | 7242 |
7213 // Set the debug break to enter the debugger as soon as possible. | 7243 // Function with infinite loop. |
7214 v8::Debug::DebugBreak(); | 7244 CompileRun(buffer.start()); |
7215 | 7245 |
7216 // Call function with infinite loop. | 7246 // Set the debug break to enter the debugger as soon as possible. |
7217 CompileRun("f();"); | 7247 v8::Debug::DebugBreak(); |
7218 CHECK_EQ(count * 100, break_point_hit_count); | |
7219 | 7248 |
7220 CHECK(!v8::V8::IsExecutionTerminating()); | 7249 // Call function with infinite loop. |
| 7250 CompileRun("f();"); |
| 7251 CHECK_EQ(kBreaksPerTest, break_point_hit_count); |
| 7252 |
| 7253 CHECK(!v8::V8::IsExecutionTerminating()); |
| 7254 } |
7221 } | 7255 } |
7222 } | 7256 } |
7223 | 7257 |
7224 | 7258 |
7225 TEST(DebugBreakLoop) { | 7259 TEST(DebugBreakLoop) { |
7226 v8::HandleScope scope; | 7260 v8::HandleScope scope; |
7227 DebugLocalContext env; | 7261 DebugLocalContext env; |
7228 | 7262 |
7229 // Register a debug event listener which sets the break flag and counts. | 7263 // Register a debug event listener which sets the break flag and counts. |
7230 v8::Debug::SetDebugEventListener(DebugEventBreakMax); | 7264 v8::Debug::SetDebugEventListener(DebugEventBreakMax); |
7231 | 7265 |
| 7266 // Create a function for getting the frame count when hitting the break. |
| 7267 frame_count = CompileFunction(&env, frame_count_source, "frame_count"); |
| 7268 |
7232 CompileRun("var a = 1;"); | 7269 CompileRun("var a = 1;"); |
7233 CompileRun("function g() { }"); | 7270 CompileRun("function g() { }"); |
7234 CompileRun("function h() { }"); | 7271 CompileRun("function h() { }"); |
7235 | 7272 |
7236 const char* loop_bodies[] = { | 7273 const char* loop_bodies[] = { |
7237 "", | 7274 "", |
7238 "g()", | 7275 "g()", |
7239 "if (a == 0) { g() }", | 7276 "if (a == 0) { g() }", |
7240 "if (a == 1) { g() }", | 7277 "if (a == 1) { g() }", |
7241 "if (a == 0) { g() } else { h() }", | 7278 "if (a == 0) { g() } else { h() }", |
(...skipping 15 matching lines...) Expand all Loading... |
7257 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); | 7294 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); |
7258 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); | 7295 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); |
7259 | 7296 |
7260 // Get rid of the debug event listener. | 7297 // Get rid of the debug event listener. |
7261 v8::Debug::SetDebugEventListener(NULL); | 7298 v8::Debug::SetDebugEventListener(NULL); |
7262 CheckDebuggerUnloaded(); | 7299 CheckDebuggerUnloaded(); |
7263 } | 7300 } |
7264 | 7301 |
7265 | 7302 |
7266 #endif // ENABLE_DEBUGGER_SUPPORT | 7303 #endif // ENABLE_DEBUGGER_SUPPORT |
OLD | NEW |