| OLD | NEW |
| 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifdef ENABLE_DEBUGGER_SUPPORT | 28 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 29 | 29 |
| 30 #include <stdlib.h> | 30 #include <stdlib.h> |
| 31 | 31 |
| 32 #include "v8.h" | 32 #include "v8.h" |
| 33 | 33 |
| 34 #include "api.h" | 34 #include "api.h" |
| 35 #include "cctest.h" |
| 35 #include "compilation-cache.h" | 36 #include "compilation-cache.h" |
| 36 #include "debug.h" | 37 #include "debug.h" |
| 38 #include "deoptimizer.h" |
| 37 #include "platform.h" | 39 #include "platform.h" |
| 38 #include "stub-cache.h" | 40 #include "stub-cache.h" |
| 39 #include "cctest.h" | 41 #include "utils.h" |
| 40 | 42 |
| 41 | 43 |
| 42 using ::v8::internal::EmbeddedVector; | 44 using ::v8::internal::EmbeddedVector; |
| 43 using ::v8::internal::Object; | 45 using ::v8::internal::Object; |
| 44 using ::v8::internal::OS; | 46 using ::v8::internal::OS; |
| 45 using ::v8::internal::Handle; | 47 using ::v8::internal::Handle; |
| 46 using ::v8::internal::Heap; | 48 using ::v8::internal::Heap; |
| 47 using ::v8::internal::JSGlobalProxy; | 49 using ::v8::internal::JSGlobalProxy; |
| 48 using ::v8::internal::Code; | 50 using ::v8::internal::Code; |
| 49 using ::v8::internal::Debug; | 51 using ::v8::internal::Debug; |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 } | 521 } |
| 520 } | 522 } |
| 521 | 523 |
| 522 | 524 |
| 523 // --- D e b u g E v e n t H a n d l e r s | 525 // --- D e b u g E v e n t H a n d l e r s |
| 524 // --- | 526 // --- |
| 525 // --- The different tests uses a number of debug event handlers. | 527 // --- The different tests uses a number of debug event handlers. |
| 526 // --- | 528 // --- |
| 527 | 529 |
| 528 | 530 |
| 529 // Source for The JavaScript function which picks out the function name of the | 531 // Source for the JavaScript function which picks out the function |
| 530 // top frame. | 532 // name of a frame. |
| 531 const char* frame_function_name_source = | 533 const char* frame_function_name_source = |
| 532 "function frame_function_name(exec_state) {" | 534 "function frame_function_name(exec_state, frame_number) {" |
| 533 " return exec_state.frame(0).func().name();" | 535 " return exec_state.frame(frame_number).func().name();" |
| 534 "}"; | 536 "}"; |
| 535 v8::Local<v8::Function> frame_function_name; | 537 v8::Local<v8::Function> frame_function_name; |
| 536 | 538 |
| 537 | 539 |
| 538 // Source for The JavaScript function which picks out the source line for the | 540 // Source for the JavaScript function which pick out the name of the |
| 541 // first argument of a frame. |
| 542 const char* frame_argument_name_source = |
| 543 "function frame_argument_name(exec_state, frame_number) {" |
| 544 " return exec_state.frame(frame_number).argumentName(0);" |
| 545 "}"; |
| 546 v8::Local<v8::Function> frame_argument_name; |
| 547 |
| 548 |
| 549 // Source for the JavaScript function which pick out the value of the |
| 550 // first argument of a frame. |
| 551 const char* frame_argument_value_source = |
| 552 "function frame_argument_value(exec_state, frame_number) {" |
| 553 " return exec_state.frame(frame_number).argumentValue(0).value_;" |
| 554 "}"; |
| 555 v8::Local<v8::Function> frame_argument_value; |
| 556 |
| 557 |
| 558 // Source for the JavaScript function which pick out the name of the |
| 559 // first argument of a frame. |
| 560 const char* frame_local_name_source = |
| 561 "function frame_local_name(exec_state, frame_number) {" |
| 562 " return exec_state.frame(frame_number).localName(0);" |
| 563 "}"; |
| 564 v8::Local<v8::Function> frame_local_name; |
| 565 |
| 566 |
| 567 // Source for the JavaScript function which pick out the value of the |
| 568 // first argument of a frame. |
| 569 const char* frame_local_value_source = |
| 570 "function frame_local_value(exec_state, frame_number) {" |
| 571 " return exec_state.frame(frame_number).localValue(0).value_;" |
| 572 "}"; |
| 573 v8::Local<v8::Function> frame_local_value; |
| 574 |
| 575 |
| 576 // Source for the JavaScript function which picks out the source line for the |
| 539 // top frame. | 577 // top frame. |
| 540 const char* frame_source_line_source = | 578 const char* frame_source_line_source = |
| 541 "function frame_source_line(exec_state) {" | 579 "function frame_source_line(exec_state) {" |
| 542 " return exec_state.frame(0).sourceLine();" | 580 " return exec_state.frame(0).sourceLine();" |
| 543 "}"; | 581 "}"; |
| 544 v8::Local<v8::Function> frame_source_line; | 582 v8::Local<v8::Function> frame_source_line; |
| 545 | 583 |
| 546 | 584 |
| 547 // Source for The JavaScript function which picks out the source column for the | 585 // Source for the JavaScript function which picks out the source column for the |
| 548 // top frame. | 586 // top frame. |
| 549 const char* frame_source_column_source = | 587 const char* frame_source_column_source = |
| 550 "function frame_source_column(exec_state) {" | 588 "function frame_source_column(exec_state) {" |
| 551 " return exec_state.frame(0).sourceColumn();" | 589 " return exec_state.frame(0).sourceColumn();" |
| 552 "}"; | 590 "}"; |
| 553 v8::Local<v8::Function> frame_source_column; | 591 v8::Local<v8::Function> frame_source_column; |
| 554 | 592 |
| 555 | 593 |
| 556 // Source for The JavaScript function which picks out the script name for the | 594 // Source for the JavaScript function which picks out the script name for the |
| 557 // top frame. | 595 // top frame. |
| 558 const char* frame_script_name_source = | 596 const char* frame_script_name_source = |
| 559 "function frame_script_name(exec_state) {" | 597 "function frame_script_name(exec_state) {" |
| 560 " return exec_state.frame(0).func().script().name();" | 598 " return exec_state.frame(0).func().script().name();" |
| 561 "}"; | 599 "}"; |
| 562 v8::Local<v8::Function> frame_script_name; | 600 v8::Local<v8::Function> frame_script_name; |
| 563 | 601 |
| 564 | 602 |
| 565 // Source for The JavaScript function which picks out the script data for the | 603 // Source for the JavaScript function which picks out the script data for the |
| 566 // top frame. | 604 // top frame. |
| 567 const char* frame_script_data_source = | 605 const char* frame_script_data_source = |
| 568 "function frame_script_data(exec_state) {" | 606 "function frame_script_data(exec_state) {" |
| 569 " return exec_state.frame(0).func().script().data();" | 607 " return exec_state.frame(0).func().script().data();" |
| 570 "}"; | 608 "}"; |
| 571 v8::Local<v8::Function> frame_script_data; | 609 v8::Local<v8::Function> frame_script_data; |
| 572 | 610 |
| 573 | 611 |
| 574 // Source for The JavaScript function which picks out the script data from | 612 // Source for the JavaScript function which picks out the script data from |
| 575 // AfterCompile event | 613 // AfterCompile event |
| 576 const char* compiled_script_data_source = | 614 const char* compiled_script_data_source = |
| 577 "function compiled_script_data(event_data) {" | 615 "function compiled_script_data(event_data) {" |
| 578 " return event_data.script().data();" | 616 " return event_data.script().data();" |
| 579 "}"; | 617 "}"; |
| 580 v8::Local<v8::Function> compiled_script_data; | 618 v8::Local<v8::Function> compiled_script_data; |
| 581 | 619 |
| 582 | 620 |
| 583 // Source for The JavaScript function which returns the number of frames. | 621 // Source for the JavaScript function which returns the number of frames. |
| 584 static const char* frame_count_source = | 622 static const char* frame_count_source = |
| 585 "function frame_count(exec_state) {" | 623 "function frame_count(exec_state) {" |
| 586 " return exec_state.frameCount();" | 624 " return exec_state.frameCount();" |
| 587 "}"; | 625 "}"; |
| 588 v8::Handle<v8::Function> frame_count; | 626 v8::Handle<v8::Function> frame_count; |
| 589 | 627 |
| 590 | 628 |
| 591 // Global variable to store the last function hit - used by some tests. | 629 // Global variable to store the last function hit - used by some tests. |
| 592 char last_function_hit[80]; | 630 char last_function_hit[80]; |
| 593 | 631 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 608 v8::Handle<v8::Value> data) { | 646 v8::Handle<v8::Value> data) { |
| 609 Debug* debug = v8::internal::Isolate::Current()->debug(); | 647 Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 610 // When hitting a debug event listener there must be a break set. | 648 // When hitting a debug event listener there must be a break set. |
| 611 CHECK_NE(debug->break_id(), 0); | 649 CHECK_NE(debug->break_id(), 0); |
| 612 | 650 |
| 613 // Count the number of breaks. | 651 // Count the number of breaks. |
| 614 if (event == v8::Break) { | 652 if (event == v8::Break) { |
| 615 break_point_hit_count++; | 653 break_point_hit_count++; |
| 616 if (!frame_function_name.IsEmpty()) { | 654 if (!frame_function_name.IsEmpty()) { |
| 617 // Get the name of the function. | 655 // Get the name of the function. |
| 618 const int argc = 1; | 656 const int argc = 2; |
| 619 v8::Handle<v8::Value> argv[argc] = { exec_state }; | 657 v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; |
| 620 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, | 658 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, |
| 621 argc, argv); | 659 argc, argv); |
| 622 if (result->IsUndefined()) { | 660 if (result->IsUndefined()) { |
| 623 last_function_hit[0] = '\0'; | 661 last_function_hit[0] = '\0'; |
| 624 } else { | 662 } else { |
| 625 CHECK(result->IsString()); | 663 CHECK(result->IsString()); |
| 626 v8::Handle<v8::String> function_name(result->ToString()); | 664 v8::Handle<v8::String> function_name(result->ToString()); |
| 627 function_name->WriteAscii(last_function_hit); | 665 function_name->WriteAscii(last_function_hit); |
| 628 } | 666 } |
| 629 } | 667 } |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 v8::Handle<v8::Object> event_data, | 883 v8::Handle<v8::Object> event_data, |
| 846 v8::Handle<v8::Value> data) { | 884 v8::Handle<v8::Value> data) { |
| 847 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); | 885 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 848 // When hitting a debug event listener there must be a break set. | 886 // When hitting a debug event listener there must be a break set. |
| 849 CHECK_NE(debug->break_id(), 0); | 887 CHECK_NE(debug->break_id(), 0); |
| 850 | 888 |
| 851 if (event == v8::Break || event == v8::Exception) { | 889 if (event == v8::Break || event == v8::Exception) { |
| 852 // Check that the current function is the expected. | 890 // Check that the current function is the expected. |
| 853 CHECK(break_point_hit_count < | 891 CHECK(break_point_hit_count < |
| 854 StrLength(expected_step_sequence)); | 892 StrLength(expected_step_sequence)); |
| 855 const int argc = 1; | 893 const int argc = 2; |
| 856 v8::Handle<v8::Value> argv[argc] = { exec_state }; | 894 v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; |
| 857 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, | 895 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, |
| 858 argc, argv); | 896 argc, argv); |
| 859 CHECK(result->IsString()); | 897 CHECK(result->IsString()); |
| 860 v8::String::AsciiValue function_name(result->ToString()); | 898 v8::String::AsciiValue function_name(result->ToString()); |
| 861 CHECK_EQ(1, StrLength(*function_name)); | 899 CHECK_EQ(1, StrLength(*function_name)); |
| 862 CHECK_EQ((*function_name)[0], | 900 CHECK_EQ((*function_name)[0], |
| 863 expected_step_sequence[break_point_hit_count]); | 901 expected_step_sequence[break_point_hit_count]); |
| 864 | 902 |
| 865 // Perform step. | 903 // Perform step. |
| 866 break_point_hit_count++; | 904 break_point_hit_count++; |
| (...skipping 1738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2605 | 2643 |
| 2606 // Simple test of the stepping mechanism using only store ICs. | 2644 // Simple test of the stepping mechanism using only store ICs. |
| 2607 TEST(DebugStepLinear) { | 2645 TEST(DebugStepLinear) { |
| 2608 v8::HandleScope scope; | 2646 v8::HandleScope scope; |
| 2609 DebugLocalContext env; | 2647 DebugLocalContext env; |
| 2610 | 2648 |
| 2611 // Create a function for testing stepping. | 2649 // Create a function for testing stepping. |
| 2612 v8::Local<v8::Function> foo = CompileFunction(&env, | 2650 v8::Local<v8::Function> foo = CompileFunction(&env, |
| 2613 "function foo(){a=1;b=1;c=1;}", | 2651 "function foo(){a=1;b=1;c=1;}", |
| 2614 "foo"); | 2652 "foo"); |
| 2653 |
| 2654 // Run foo to allow it to get optimized. |
| 2655 CompileRun("a=0; b=0; c=0; foo();"); |
| 2656 |
| 2615 SetBreakPoint(foo, 3); | 2657 SetBreakPoint(foo, 3); |
| 2616 | 2658 |
| 2617 // Register a debug event listener which steps and counts. | 2659 // Register a debug event listener which steps and counts. |
| 2618 v8::Debug::SetDebugEventListener(DebugEventStep); | 2660 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2619 | 2661 |
| 2620 step_action = StepIn; | 2662 step_action = StepIn; |
| 2621 break_point_hit_count = 0; | 2663 break_point_hit_count = 0; |
| 2622 foo->Call(env->Global(), 0, NULL); | 2664 foo->Call(env->Global(), 0, NULL); |
| 2623 | 2665 |
| 2624 // With stepping all break locations are hit. | 2666 // With stepping all break locations are hit. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2654 // is there to have more than one breakable statement in the loop, TODO(315). | 2696 // is there to have more than one breakable statement in the loop, TODO(315). |
| 2655 v8::Local<v8::Function> foo = CompileFunction( | 2697 v8::Local<v8::Function> foo = CompileFunction( |
| 2656 &env, | 2698 &env, |
| 2657 "function foo(a) {\n" | 2699 "function foo(a) {\n" |
| 2658 " var x;\n" | 2700 " var x;\n" |
| 2659 " var len = a.length;\n" | 2701 " var len = a.length;\n" |
| 2660 " for (var i = 0; i < len; i++) {\n" | 2702 " for (var i = 0; i < len; i++) {\n" |
| 2661 " y = 1;\n" | 2703 " y = 1;\n" |
| 2662 " x = a[i];\n" | 2704 " x = a[i];\n" |
| 2663 " }\n" | 2705 " }\n" |
| 2664 "}\n", | 2706 "}\n" |
| 2707 "y=0\n", |
| 2665 "foo"); | 2708 "foo"); |
| 2666 | 2709 |
| 2667 // Create array [0,1,2,3,4,5,6,7,8,9] | 2710 // Create array [0,1,2,3,4,5,6,7,8,9] |
| 2668 v8::Local<v8::Array> a = v8::Array::New(10); | 2711 v8::Local<v8::Array> a = v8::Array::New(10); |
| 2669 for (int i = 0; i < 10; i++) { | 2712 for (int i = 0; i < 10; i++) { |
| 2670 a->Set(v8::Number::New(i), v8::Number::New(i)); | 2713 a->Set(v8::Number::New(i), v8::Number::New(i)); |
| 2671 } | 2714 } |
| 2672 | 2715 |
| 2673 // Call function without any break points to ensure inlining is in place. | 2716 // Call function without any break points to ensure inlining is in place. |
| 2674 const int kArgc = 1; | 2717 const int kArgc = 1; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2700 // Create a function for testing stepping of keyed store. The statement 'y=1' | 2743 // Create a function for testing stepping of keyed store. The statement 'y=1' |
| 2701 // is there to have more than one breakable statement in the loop, TODO(315). | 2744 // is there to have more than one breakable statement in the loop, TODO(315). |
| 2702 v8::Local<v8::Function> foo = CompileFunction( | 2745 v8::Local<v8::Function> foo = CompileFunction( |
| 2703 &env, | 2746 &env, |
| 2704 "function foo(a) {\n" | 2747 "function foo(a) {\n" |
| 2705 " var len = a.length;\n" | 2748 " var len = a.length;\n" |
| 2706 " for (var i = 0; i < len; i++) {\n" | 2749 " for (var i = 0; i < len; i++) {\n" |
| 2707 " y = 1;\n" | 2750 " y = 1;\n" |
| 2708 " a[i] = 42;\n" | 2751 " a[i] = 42;\n" |
| 2709 " }\n" | 2752 " }\n" |
| 2710 "}\n", | 2753 "}\n" |
| 2754 "y=0\n", |
| 2711 "foo"); | 2755 "foo"); |
| 2712 | 2756 |
| 2713 // Create array [0,1,2,3,4,5,6,7,8,9] | 2757 // Create array [0,1,2,3,4,5,6,7,8,9] |
| 2714 v8::Local<v8::Array> a = v8::Array::New(10); | 2758 v8::Local<v8::Array> a = v8::Array::New(10); |
| 2715 for (int i = 0; i < 10; i++) { | 2759 for (int i = 0; i < 10; i++) { |
| 2716 a->Set(v8::Number::New(i), v8::Number::New(i)); | 2760 a->Set(v8::Number::New(i), v8::Number::New(i)); |
| 2717 } | 2761 } |
| 2718 | 2762 |
| 2719 // Call function without any break points to ensure inlining is in place. | 2763 // Call function without any break points to ensure inlining is in place. |
| 2720 const int kArgc = 1; | 2764 const int kArgc = 1; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2772 foo->Call(env->Global(), 0, NULL); | 2816 foo->Call(env->Global(), 0, NULL); |
| 2773 | 2817 |
| 2774 // With stepping all break locations are hit. | 2818 // With stepping all break locations are hit. |
| 2775 CHECK_EQ(53, break_point_hit_count); | 2819 CHECK_EQ(53, break_point_hit_count); |
| 2776 | 2820 |
| 2777 v8::Debug::SetDebugEventListener(NULL); | 2821 v8::Debug::SetDebugEventListener(NULL); |
| 2778 CheckDebuggerUnloaded(); | 2822 CheckDebuggerUnloaded(); |
| 2779 } | 2823 } |
| 2780 | 2824 |
| 2781 | 2825 |
| 2782 static void DoDebugStepNamedStoreLoop(int expected, bool full_compiler = true) { | 2826 static void DoDebugStepNamedStoreLoop(int expected) { |
| 2783 v8::HandleScope scope; | 2827 v8::HandleScope scope; |
| 2784 DebugLocalContext env; | 2828 DebugLocalContext env; |
| 2785 | 2829 |
| 2786 // Register a debug event listener which steps and counts before compiling the | 2830 // Register a debug event listener which steps and counts. |
| 2787 // function to ensure the full compiler is used. | 2831 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2788 if (full_compiler) { | |
| 2789 v8::Debug::SetDebugEventListener(DebugEventStep); | |
| 2790 } | |
| 2791 | 2832 |
| 2792 // Create a function for testing stepping of named store. | 2833 // Create a function for testing stepping of named store. |
| 2793 v8::Local<v8::Function> foo = CompileFunction( | 2834 v8::Local<v8::Function> foo = CompileFunction( |
| 2794 &env, | 2835 &env, |
| 2795 "function foo() {\n" | 2836 "function foo() {\n" |
| 2796 " var a = {a:1};\n" | 2837 " var a = {a:1};\n" |
| 2797 " for (var i = 0; i < 10; i++) {\n" | 2838 " for (var i = 0; i < 10; i++) {\n" |
| 2798 " a.a = 2\n" | 2839 " a.a = 2\n" |
| 2799 " }\n" | 2840 " }\n" |
| 2800 "}\n", | 2841 "}\n", |
| 2801 "foo"); | 2842 "foo"); |
| 2802 | 2843 |
| 2803 // Call function without any break points to ensure inlining is in place. | 2844 // Call function without any break points to ensure inlining is in place. |
| 2804 foo->Call(env->Global(), 0, NULL); | 2845 foo->Call(env->Global(), 0, NULL); |
| 2805 | 2846 |
| 2806 // Register a debug event listener which steps and counts after compiling the | |
| 2807 // function to ensure the optimizing compiler is used. | |
| 2808 if (!full_compiler) { | |
| 2809 v8::Debug::SetDebugEventListener(DebugEventStep); | |
| 2810 } | |
| 2811 | |
| 2812 // Setup break point and step through the function. | 2847 // Setup break point and step through the function. |
| 2813 SetBreakPoint(foo, 3); | 2848 SetBreakPoint(foo, 3); |
| 2814 step_action = StepNext; | 2849 step_action = StepNext; |
| 2815 break_point_hit_count = 0; | 2850 break_point_hit_count = 0; |
| 2816 foo->Call(env->Global(), 0, NULL); | 2851 foo->Call(env->Global(), 0, NULL); |
| 2817 | 2852 |
| 2818 // With stepping all expected break locations are hit. | 2853 // With stepping all expected break locations are hit. |
| 2819 CHECK_EQ(expected, break_point_hit_count); | 2854 CHECK_EQ(expected, break_point_hit_count); |
| 2820 | 2855 |
| 2821 v8::Debug::SetDebugEventListener(NULL); | 2856 v8::Debug::SetDebugEventListener(NULL); |
| 2822 CheckDebuggerUnloaded(); | 2857 CheckDebuggerUnloaded(); |
| 2823 } | 2858 } |
| 2824 | 2859 |
| 2825 | 2860 |
| 2826 // Test of the stepping mechanism for named load in a loop. | 2861 // Test of the stepping mechanism for named load in a loop. |
| 2827 TEST(DebugStepNamedStoreLoopFull) { | 2862 TEST(DebugStepNamedStoreLoop) { |
| 2828 // With the full compiler it is possible to break on the for statement. | |
| 2829 DoDebugStepNamedStoreLoop(22); | 2863 DoDebugStepNamedStoreLoop(22); |
| 2830 } | 2864 } |
| 2831 | 2865 |
| 2832 | 2866 |
| 2833 // Test of the stepping mechanism for named load in a loop. | |
| 2834 TEST(DebugStepNamedStoreLoopOptimizing) { | |
| 2835 // With the optimizing compiler it is not possible to break on the for | |
| 2836 // statement as it uses a local variable thus no IC's. | |
| 2837 DoDebugStepNamedStoreLoop(11, false); | |
| 2838 } | |
| 2839 | |
| 2840 | |
| 2841 // Test the stepping mechanism with different ICs. | 2867 // Test the stepping mechanism with different ICs. |
| 2842 TEST(DebugStepLinearMixedICs) { | 2868 TEST(DebugStepLinearMixedICs) { |
| 2843 v8::HandleScope scope; | 2869 v8::HandleScope scope; |
| 2844 DebugLocalContext env; | 2870 DebugLocalContext env; |
| 2845 | 2871 |
| 2846 // Register a debug event listener which steps and counts. | 2872 // Register a debug event listener which steps and counts. |
| 2847 v8::Debug::SetDebugEventListener(DebugEventStep); | 2873 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2848 | 2874 |
| 2849 // Create a function for testing stepping. | 2875 // Create a function for testing stepping. |
| 2850 v8::Local<v8::Function> foo = CompileFunction(&env, | 2876 v8::Local<v8::Function> foo = CompileFunction(&env, |
| 2851 "function bar() {};" | 2877 "function bar() {};" |
| 2852 "function foo() {" | 2878 "function foo() {" |
| 2853 " var x;" | 2879 " var x;" |
| 2854 " var index='name';" | 2880 " var index='name';" |
| 2855 " var y = {};" | 2881 " var y = {};" |
| 2856 " a=1;b=2;x=a;y[index]=3;x=y[index];bar();}", "foo"); | 2882 " a=1;b=2;x=a;y[index]=3;x=y[index];bar();}", "foo"); |
| 2883 |
| 2884 // Run functions to allow them to get optimized. |
| 2885 CompileRun("a=0; b=0; bar(); foo();"); |
| 2886 |
| 2857 SetBreakPoint(foo, 0); | 2887 SetBreakPoint(foo, 0); |
| 2858 | 2888 |
| 2859 step_action = StepIn; | 2889 step_action = StepIn; |
| 2860 break_point_hit_count = 0; | 2890 break_point_hit_count = 0; |
| 2861 foo->Call(env->Global(), 0, NULL); | 2891 foo->Call(env->Global(), 0, NULL); |
| 2862 | 2892 |
| 2863 // With stepping all break locations are hit. | 2893 // With stepping all break locations are hit. |
| 2864 CHECK_EQ(11, break_point_hit_count); | 2894 CHECK_EQ(11, break_point_hit_count); |
| 2865 | 2895 |
| 2866 v8::Debug::SetDebugEventListener(NULL); | 2896 v8::Debug::SetDebugEventListener(NULL); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2881 } | 2911 } |
| 2882 | 2912 |
| 2883 | 2913 |
| 2884 TEST(DebugStepDeclarations) { | 2914 TEST(DebugStepDeclarations) { |
| 2885 v8::HandleScope scope; | 2915 v8::HandleScope scope; |
| 2886 DebugLocalContext env; | 2916 DebugLocalContext env; |
| 2887 | 2917 |
| 2888 // Register a debug event listener which steps and counts. | 2918 // Register a debug event listener which steps and counts. |
| 2889 v8::Debug::SetDebugEventListener(DebugEventStep); | 2919 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2890 | 2920 |
| 2891 // Create a function for testing stepping. | 2921 // Create a function for testing stepping. Run it to allow it to get |
| 2922 // optimized. |
| 2892 const char* src = "function foo() { " | 2923 const char* src = "function foo() { " |
| 2893 " var a;" | 2924 " var a;" |
| 2894 " var b = 1;" | 2925 " var b = 1;" |
| 2895 " var c = foo;" | 2926 " var c = foo;" |
| 2896 " var d = Math.floor;" | 2927 " var d = Math.floor;" |
| 2897 " var e = b + d(1.2);" | 2928 " var e = b + d(1.2);" |
| 2898 "}"; | 2929 "}" |
| 2930 "foo()"; |
| 2899 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 2931 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 2932 |
| 2900 SetBreakPoint(foo, 0); | 2933 SetBreakPoint(foo, 0); |
| 2901 | 2934 |
| 2902 // Stepping through the declarations. | 2935 // Stepping through the declarations. |
| 2903 step_action = StepIn; | 2936 step_action = StepIn; |
| 2904 break_point_hit_count = 0; | 2937 break_point_hit_count = 0; |
| 2905 foo->Call(env->Global(), 0, NULL); | 2938 foo->Call(env->Global(), 0, NULL); |
| 2906 CHECK_EQ(6, break_point_hit_count); | 2939 CHECK_EQ(6, break_point_hit_count); |
| 2907 | 2940 |
| 2908 // Get rid of the debug event listener. | 2941 // Get rid of the debug event listener. |
| 2909 v8::Debug::SetDebugEventListener(NULL); | 2942 v8::Debug::SetDebugEventListener(NULL); |
| 2910 CheckDebuggerUnloaded(); | 2943 CheckDebuggerUnloaded(); |
| 2911 } | 2944 } |
| 2912 | 2945 |
| 2913 | 2946 |
| 2914 TEST(DebugStepLocals) { | 2947 TEST(DebugStepLocals) { |
| 2915 v8::HandleScope scope; | 2948 v8::HandleScope scope; |
| 2916 DebugLocalContext env; | 2949 DebugLocalContext env; |
| 2917 | 2950 |
| 2918 // Register a debug event listener which steps and counts. | 2951 // Register a debug event listener which steps and counts. |
| 2919 v8::Debug::SetDebugEventListener(DebugEventStep); | 2952 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2920 | 2953 |
| 2921 // Create a function for testing stepping. | 2954 // Create a function for testing stepping. Run it to allow it to get |
| 2955 // optimized. |
| 2922 const char* src = "function foo() { " | 2956 const char* src = "function foo() { " |
| 2923 " var a,b;" | 2957 " var a,b;" |
| 2924 " a = 1;" | 2958 " a = 1;" |
| 2925 " b = a + 2;" | 2959 " b = a + 2;" |
| 2926 " b = 1 + 2 + 3;" | 2960 " b = 1 + 2 + 3;" |
| 2927 " a = Math.floor(b);" | 2961 " a = Math.floor(b);" |
| 2928 "}"; | 2962 "}" |
| 2963 "foo()"; |
| 2929 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 2964 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 2965 |
| 2930 SetBreakPoint(foo, 0); | 2966 SetBreakPoint(foo, 0); |
| 2931 | 2967 |
| 2932 // Stepping through the declarations. | 2968 // Stepping through the declarations. |
| 2933 step_action = StepIn; | 2969 step_action = StepIn; |
| 2934 break_point_hit_count = 0; | 2970 break_point_hit_count = 0; |
| 2935 foo->Call(env->Global(), 0, NULL); | 2971 foo->Call(env->Global(), 0, NULL); |
| 2936 CHECK_EQ(6, break_point_hit_count); | 2972 CHECK_EQ(6, break_point_hit_count); |
| 2937 | 2973 |
| 2938 // Get rid of the debug event listener. | 2974 // Get rid of the debug event listener. |
| 2939 v8::Debug::SetDebugEventListener(NULL); | 2975 v8::Debug::SetDebugEventListener(NULL); |
| 2940 CheckDebuggerUnloaded(); | 2976 CheckDebuggerUnloaded(); |
| 2941 } | 2977 } |
| 2942 | 2978 |
| 2943 | 2979 |
| 2944 TEST(DebugStepIf) { | 2980 TEST(DebugStepIf) { |
| 2945 v8::HandleScope scope; | 2981 v8::HandleScope scope; |
| 2946 DebugLocalContext env; | 2982 DebugLocalContext env; |
| 2947 | 2983 |
| 2948 // Register a debug event listener which steps and counts. | 2984 // Register a debug event listener which steps and counts. |
| 2949 v8::Debug::SetDebugEventListener(DebugEventStep); | 2985 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2950 | 2986 |
| 2951 // Create a function for testing stepping. | 2987 // Create a function for testing stepping. Run it to allow it to get |
| 2988 // optimized. |
| 2952 const int argc = 1; | 2989 const int argc = 1; |
| 2953 const char* src = "function foo(x) { " | 2990 const char* src = "function foo(x) { " |
| 2954 " a = 1;" | 2991 " a = 1;" |
| 2955 " if (x) {" | 2992 " if (x) {" |
| 2956 " b = 1;" | 2993 " b = 1;" |
| 2957 " } else {" | 2994 " } else {" |
| 2958 " c = 1;" | 2995 " c = 1;" |
| 2959 " d = 1;" | 2996 " d = 1;" |
| 2960 " }" | 2997 " }" |
| 2961 "}"; | 2998 "}" |
| 2999 "a=0; b=0; c=0; d=0; foo()"; |
| 2962 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3000 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 2963 SetBreakPoint(foo, 0); | 3001 SetBreakPoint(foo, 0); |
| 2964 | 3002 |
| 2965 // Stepping through the true part. | 3003 // Stepping through the true part. |
| 2966 step_action = StepIn; | 3004 step_action = StepIn; |
| 2967 break_point_hit_count = 0; | 3005 break_point_hit_count = 0; |
| 2968 v8::Handle<v8::Value> argv_true[argc] = { v8::True() }; | 3006 v8::Handle<v8::Value> argv_true[argc] = { v8::True() }; |
| 2969 foo->Call(env->Global(), argc, argv_true); | 3007 foo->Call(env->Global(), argc, argv_true); |
| 2970 CHECK_EQ(4, break_point_hit_count); | 3008 CHECK_EQ(4, break_point_hit_count); |
| 2971 | 3009 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2982 } | 3020 } |
| 2983 | 3021 |
| 2984 | 3022 |
| 2985 TEST(DebugStepSwitch) { | 3023 TEST(DebugStepSwitch) { |
| 2986 v8::HandleScope scope; | 3024 v8::HandleScope scope; |
| 2987 DebugLocalContext env; | 3025 DebugLocalContext env; |
| 2988 | 3026 |
| 2989 // Register a debug event listener which steps and counts. | 3027 // Register a debug event listener which steps and counts. |
| 2990 v8::Debug::SetDebugEventListener(DebugEventStep); | 3028 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2991 | 3029 |
| 2992 // Create a function for testing stepping. | 3030 // Create a function for testing stepping. Run it to allow it to get |
| 3031 // optimized. |
| 2993 const int argc = 1; | 3032 const int argc = 1; |
| 2994 const char* src = "function foo(x) { " | 3033 const char* src = "function foo(x) { " |
| 2995 " a = 1;" | 3034 " a = 1;" |
| 2996 " switch (x) {" | 3035 " switch (x) {" |
| 2997 " case 1:" | 3036 " case 1:" |
| 2998 " b = 1;" | 3037 " b = 1;" |
| 2999 " case 2:" | 3038 " case 2:" |
| 3000 " c = 1;" | 3039 " c = 1;" |
| 3001 " break;" | 3040 " break;" |
| 3002 " case 3:" | 3041 " case 3:" |
| 3003 " d = 1;" | 3042 " d = 1;" |
| 3004 " e = 1;" | 3043 " e = 1;" |
| 3005 " f = 1;" | 3044 " f = 1;" |
| 3006 " break;" | 3045 " break;" |
| 3007 " }" | 3046 " }" |
| 3008 "}"; | 3047 "}" |
| 3048 "a=0; b=0; c=0; d=0; e=0; f=0; foo()"; |
| 3009 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3049 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3010 SetBreakPoint(foo, 0); | 3050 SetBreakPoint(foo, 0); |
| 3011 | 3051 |
| 3012 // One case with fall-through. | 3052 // One case with fall-through. |
| 3013 step_action = StepIn; | 3053 step_action = StepIn; |
| 3014 break_point_hit_count = 0; | 3054 break_point_hit_count = 0; |
| 3015 v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(1) }; | 3055 v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(1) }; |
| 3016 foo->Call(env->Global(), argc, argv_1); | 3056 foo->Call(env->Global(), argc, argv_1); |
| 3017 CHECK_EQ(6, break_point_hit_count); | 3057 CHECK_EQ(6, break_point_hit_count); |
| 3018 | 3058 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3036 } | 3076 } |
| 3037 | 3077 |
| 3038 | 3078 |
| 3039 TEST(DebugStepWhile) { | 3079 TEST(DebugStepWhile) { |
| 3040 v8::HandleScope scope; | 3080 v8::HandleScope scope; |
| 3041 DebugLocalContext env; | 3081 DebugLocalContext env; |
| 3042 | 3082 |
| 3043 // Register a debug event listener which steps and counts. | 3083 // Register a debug event listener which steps and counts. |
| 3044 v8::Debug::SetDebugEventListener(DebugEventStep); | 3084 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3045 | 3085 |
| 3046 // Create a function for testing stepping. | 3086 // Create a function for testing stepping. Run it to allow it to get |
| 3087 // optimized. |
| 3047 const int argc = 1; | 3088 const int argc = 1; |
| 3048 const char* src = "function foo(x) { " | 3089 const char* src = "function foo(x) { " |
| 3049 " var a = 0;" | 3090 " var a = 0;" |
| 3050 " while (a < x) {" | 3091 " while (a < x) {" |
| 3051 " a++;" | 3092 " a++;" |
| 3052 " }" | 3093 " }" |
| 3053 "}"; | 3094 "}" |
| 3095 "foo()"; |
| 3054 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3096 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3055 SetBreakPoint(foo, 8); // "var a = 0;" | 3097 SetBreakPoint(foo, 8); // "var a = 0;" |
| 3056 | 3098 |
| 3057 // Looping 10 times. | 3099 // Looping 10 times. |
| 3058 step_action = StepIn; | 3100 step_action = StepIn; |
| 3059 break_point_hit_count = 0; | 3101 break_point_hit_count = 0; |
| 3060 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; | 3102 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; |
| 3061 foo->Call(env->Global(), argc, argv_10); | 3103 foo->Call(env->Global(), argc, argv_10); |
| 3062 CHECK_EQ(23, break_point_hit_count); | 3104 CHECK_EQ(22, break_point_hit_count); |
| 3063 | 3105 |
| 3064 // Looping 100 times. | 3106 // Looping 100 times. |
| 3065 step_action = StepIn; | 3107 step_action = StepIn; |
| 3066 break_point_hit_count = 0; | 3108 break_point_hit_count = 0; |
| 3067 v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; | 3109 v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; |
| 3068 foo->Call(env->Global(), argc, argv_100); | 3110 foo->Call(env->Global(), argc, argv_100); |
| 3069 CHECK_EQ(203, break_point_hit_count); | 3111 CHECK_EQ(202, break_point_hit_count); |
| 3070 | 3112 |
| 3071 // Get rid of the debug event listener. | 3113 // Get rid of the debug event listener. |
| 3072 v8::Debug::SetDebugEventListener(NULL); | 3114 v8::Debug::SetDebugEventListener(NULL); |
| 3073 CheckDebuggerUnloaded(); | 3115 CheckDebuggerUnloaded(); |
| 3074 } | 3116 } |
| 3075 | 3117 |
| 3076 | 3118 |
| 3077 TEST(DebugStepDoWhile) { | 3119 TEST(DebugStepDoWhile) { |
| 3078 v8::HandleScope scope; | 3120 v8::HandleScope scope; |
| 3079 DebugLocalContext env; | 3121 DebugLocalContext env; |
| 3080 | 3122 |
| 3081 // Register a debug event listener which steps and counts. | 3123 // Register a debug event listener which steps and counts. |
| 3082 v8::Debug::SetDebugEventListener(DebugEventStep); | 3124 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3083 | 3125 |
| 3084 // Create a function for testing stepping. | 3126 // Create a function for testing stepping. Run it to allow it to get |
| 3127 // optimized. |
| 3085 const int argc = 1; | 3128 const int argc = 1; |
| 3086 const char* src = "function foo(x) { " | 3129 const char* src = "function foo(x) { " |
| 3087 " var a = 0;" | 3130 " var a = 0;" |
| 3088 " do {" | 3131 " do {" |
| 3089 " a++;" | 3132 " a++;" |
| 3090 " } while (a < x)" | 3133 " } while (a < x)" |
| 3091 "}"; | 3134 "}" |
| 3135 "foo()"; |
| 3092 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3136 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3093 SetBreakPoint(foo, 8); // "var a = 0;" | 3137 SetBreakPoint(foo, 8); // "var a = 0;" |
| 3094 | 3138 |
| 3095 // Looping 10 times. | 3139 // Looping 10 times. |
| 3096 step_action = StepIn; | 3140 step_action = StepIn; |
| 3097 break_point_hit_count = 0; | 3141 break_point_hit_count = 0; |
| 3098 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; | 3142 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; |
| 3099 foo->Call(env->Global(), argc, argv_10); | 3143 foo->Call(env->Global(), argc, argv_10); |
| 3100 CHECK_EQ(22, break_point_hit_count); | 3144 CHECK_EQ(22, break_point_hit_count); |
| 3101 | 3145 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3112 } | 3156 } |
| 3113 | 3157 |
| 3114 | 3158 |
| 3115 TEST(DebugStepFor) { | 3159 TEST(DebugStepFor) { |
| 3116 v8::HandleScope scope; | 3160 v8::HandleScope scope; |
| 3117 DebugLocalContext env; | 3161 DebugLocalContext env; |
| 3118 | 3162 |
| 3119 // Register a debug event listener which steps and counts. | 3163 // Register a debug event listener which steps and counts. |
| 3120 v8::Debug::SetDebugEventListener(DebugEventStep); | 3164 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3121 | 3165 |
| 3122 // Create a function for testing stepping. | 3166 // Create a function for testing stepping. Run it to allow it to get |
| 3167 // optimized. |
| 3123 const int argc = 1; | 3168 const int argc = 1; |
| 3124 const char* src = "function foo(x) { " | 3169 const char* src = "function foo(x) { " |
| 3125 " a = 1;" | 3170 " a = 1;" |
| 3126 " for (i = 0; i < x; i++) {" | 3171 " for (i = 0; i < x; i++) {" |
| 3127 " b = 1;" | 3172 " b = 1;" |
| 3128 " }" | 3173 " }" |
| 3129 "}"; | 3174 "}" |
| 3175 "a=0; b=0; i=0; foo()"; |
| 3130 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3176 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3177 |
| 3131 SetBreakPoint(foo, 8); // "a = 1;" | 3178 SetBreakPoint(foo, 8); // "a = 1;" |
| 3132 | 3179 |
| 3133 // Looping 10 times. | 3180 // Looping 10 times. |
| 3134 step_action = StepIn; | 3181 step_action = StepIn; |
| 3135 break_point_hit_count = 0; | 3182 break_point_hit_count = 0; |
| 3136 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; | 3183 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; |
| 3137 foo->Call(env->Global(), argc, argv_10); | 3184 foo->Call(env->Global(), argc, argv_10); |
| 3138 CHECK_EQ(23, break_point_hit_count); | 3185 CHECK_EQ(23, break_point_hit_count); |
| 3139 | 3186 |
| 3140 // Looping 100 times. | 3187 // Looping 100 times. |
| 3141 step_action = StepIn; | 3188 step_action = StepIn; |
| 3142 break_point_hit_count = 0; | 3189 break_point_hit_count = 0; |
| 3143 v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; | 3190 v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; |
| 3144 foo->Call(env->Global(), argc, argv_100); | 3191 foo->Call(env->Global(), argc, argv_100); |
| 3145 CHECK_EQ(203, break_point_hit_count); | 3192 CHECK_EQ(203, break_point_hit_count); |
| 3146 | 3193 |
| 3147 // Get rid of the debug event listener. | 3194 // Get rid of the debug event listener. |
| 3148 v8::Debug::SetDebugEventListener(NULL); | 3195 v8::Debug::SetDebugEventListener(NULL); |
| 3149 CheckDebuggerUnloaded(); | 3196 CheckDebuggerUnloaded(); |
| 3150 } | 3197 } |
| 3151 | 3198 |
| 3152 | 3199 |
| 3153 TEST(DebugStepForContinue) { | 3200 TEST(DebugStepForContinue) { |
| 3154 v8::HandleScope scope; | 3201 v8::HandleScope scope; |
| 3155 DebugLocalContext env; | 3202 DebugLocalContext env; |
| 3156 | 3203 |
| 3157 // Register a debug event listener which steps and counts. | 3204 // Register a debug event listener which steps and counts. |
| 3158 v8::Debug::SetDebugEventListener(DebugEventStep); | 3205 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3159 | 3206 |
| 3160 // Create a function for testing stepping. | 3207 // Create a function for testing stepping. Run it to allow it to get |
| 3208 // optimized. |
| 3161 const int argc = 1; | 3209 const int argc = 1; |
| 3162 const char* src = "function foo(x) { " | 3210 const char* src = "function foo(x) { " |
| 3163 " var a = 0;" | 3211 " var a = 0;" |
| 3164 " var b = 0;" | 3212 " var b = 0;" |
| 3165 " var c = 0;" | 3213 " var c = 0;" |
| 3166 " for (var i = 0; i < x; i++) {" | 3214 " for (var i = 0; i < x; i++) {" |
| 3167 " a++;" | 3215 " a++;" |
| 3168 " if (a % 2 == 0) continue;" | 3216 " if (a % 2 == 0) continue;" |
| 3169 " b++;" | 3217 " b++;" |
| 3170 " c++;" | 3218 " c++;" |
| 3171 " }" | 3219 " }" |
| 3172 " return b;" | 3220 " return b;" |
| 3173 "}"; | 3221 "}" |
| 3222 "foo()"; |
| 3174 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3223 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3175 v8::Handle<v8::Value> result; | 3224 v8::Handle<v8::Value> result; |
| 3176 SetBreakPoint(foo, 8); // "var a = 0;" | 3225 SetBreakPoint(foo, 8); // "var a = 0;" |
| 3177 | 3226 |
| 3178 // Each loop generates 4 or 5 steps depending on whether a is equal. | 3227 // Each loop generates 4 or 5 steps depending on whether a is equal. |
| 3179 | 3228 |
| 3180 // Looping 10 times. | 3229 // Looping 10 times. |
| 3181 step_action = StepIn; | 3230 step_action = StepIn; |
| 3182 break_point_hit_count = 0; | 3231 break_point_hit_count = 0; |
| 3183 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; | 3232 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3199 } | 3248 } |
| 3200 | 3249 |
| 3201 | 3250 |
| 3202 TEST(DebugStepForBreak) { | 3251 TEST(DebugStepForBreak) { |
| 3203 v8::HandleScope scope; | 3252 v8::HandleScope scope; |
| 3204 DebugLocalContext env; | 3253 DebugLocalContext env; |
| 3205 | 3254 |
| 3206 // Register a debug event listener which steps and counts. | 3255 // Register a debug event listener which steps and counts. |
| 3207 v8::Debug::SetDebugEventListener(DebugEventStep); | 3256 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3208 | 3257 |
| 3209 // Create a function for testing stepping. | 3258 // Create a function for testing stepping. Run it to allow it to get |
| 3259 // optimized. |
| 3210 const int argc = 1; | 3260 const int argc = 1; |
| 3211 const char* src = "function foo(x) { " | 3261 const char* src = "function foo(x) { " |
| 3212 " var a = 0;" | 3262 " var a = 0;" |
| 3213 " var b = 0;" | 3263 " var b = 0;" |
| 3214 " var c = 0;" | 3264 " var c = 0;" |
| 3215 " for (var i = 0; i < 1000; i++) {" | 3265 " for (var i = 0; i < 1000; i++) {" |
| 3216 " a++;" | 3266 " a++;" |
| 3217 " if (a == x) break;" | 3267 " if (a == x) break;" |
| 3218 " b++;" | 3268 " b++;" |
| 3219 " c++;" | 3269 " c++;" |
| 3220 " }" | 3270 " }" |
| 3221 " return b;" | 3271 " return b;" |
| 3222 "}"; | 3272 "}" |
| 3273 "foo()"; |
| 3223 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3274 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3224 v8::Handle<v8::Value> result; | 3275 v8::Handle<v8::Value> result; |
| 3225 SetBreakPoint(foo, 8); // "var a = 0;" | 3276 SetBreakPoint(foo, 8); // "var a = 0;" |
| 3226 | 3277 |
| 3227 // Each loop generates 5 steps except for the last (when break is executed) | 3278 // Each loop generates 5 steps except for the last (when break is executed) |
| 3228 // which only generates 4. | 3279 // which only generates 4. |
| 3229 | 3280 |
| 3230 // Looping 10 times. | 3281 // Looping 10 times. |
| 3231 step_action = StepIn; | 3282 step_action = StepIn; |
| 3232 break_point_hit_count = 0; | 3283 break_point_hit_count = 0; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3249 } | 3300 } |
| 3250 | 3301 |
| 3251 | 3302 |
| 3252 TEST(DebugStepForIn) { | 3303 TEST(DebugStepForIn) { |
| 3253 v8::HandleScope scope; | 3304 v8::HandleScope scope; |
| 3254 DebugLocalContext env; | 3305 DebugLocalContext env; |
| 3255 | 3306 |
| 3256 // Register a debug event listener which steps and counts. | 3307 // Register a debug event listener which steps and counts. |
| 3257 v8::Debug::SetDebugEventListener(DebugEventStep); | 3308 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3258 | 3309 |
| 3310 // Create a function for testing stepping. Run it to allow it to get |
| 3311 // optimized. |
| 3259 v8::Local<v8::Function> foo; | 3312 v8::Local<v8::Function> foo; |
| 3260 const char* src_1 = "function foo() { " | 3313 const char* src_1 = "function foo() { " |
| 3261 " var a = [1, 2];" | 3314 " var a = [1, 2];" |
| 3262 " for (x in a) {" | 3315 " for (x in a) {" |
| 3263 " b = 0;" | 3316 " b = 0;" |
| 3264 " }" | 3317 " }" |
| 3265 "}"; | 3318 "}" |
| 3319 "foo()"; |
| 3266 foo = CompileFunction(&env, src_1, "foo"); | 3320 foo = CompileFunction(&env, src_1, "foo"); |
| 3267 SetBreakPoint(foo, 0); // "var a = ..." | 3321 SetBreakPoint(foo, 0); // "var a = ..." |
| 3268 | 3322 |
| 3269 step_action = StepIn; | 3323 step_action = StepIn; |
| 3270 break_point_hit_count = 0; | 3324 break_point_hit_count = 0; |
| 3271 foo->Call(env->Global(), 0, NULL); | 3325 foo->Call(env->Global(), 0, NULL); |
| 3272 CHECK_EQ(6, break_point_hit_count); | 3326 CHECK_EQ(6, break_point_hit_count); |
| 3273 | 3327 |
| 3328 // Create a function for testing stepping. Run it to allow it to get |
| 3329 // optimized. |
| 3274 const char* src_2 = "function foo() { " | 3330 const char* src_2 = "function foo() { " |
| 3275 " var a = {a:[1, 2, 3]};" | 3331 " var a = {a:[1, 2, 3]};" |
| 3276 " for (x in a.a) {" | 3332 " for (x in a.a) {" |
| 3277 " b = 0;" | 3333 " b = 0;" |
| 3278 " }" | 3334 " }" |
| 3279 "}"; | 3335 "}" |
| 3336 "foo()"; |
| 3280 foo = CompileFunction(&env, src_2, "foo"); | 3337 foo = CompileFunction(&env, src_2, "foo"); |
| 3281 SetBreakPoint(foo, 0); // "var a = ..." | 3338 SetBreakPoint(foo, 0); // "var a = ..." |
| 3282 | 3339 |
| 3283 step_action = StepIn; | 3340 step_action = StepIn; |
| 3284 break_point_hit_count = 0; | 3341 break_point_hit_count = 0; |
| 3285 foo->Call(env->Global(), 0, NULL); | 3342 foo->Call(env->Global(), 0, NULL); |
| 3286 CHECK_EQ(8, break_point_hit_count); | 3343 CHECK_EQ(8, break_point_hit_count); |
| 3287 | 3344 |
| 3288 // Get rid of the debug event listener. | 3345 // Get rid of the debug event listener. |
| 3289 v8::Debug::SetDebugEventListener(NULL); | 3346 v8::Debug::SetDebugEventListener(NULL); |
| 3290 CheckDebuggerUnloaded(); | 3347 CheckDebuggerUnloaded(); |
| 3291 } | 3348 } |
| 3292 | 3349 |
| 3293 | 3350 |
| 3294 TEST(DebugStepWith) { | 3351 TEST(DebugStepWith) { |
| 3295 v8::HandleScope scope; | 3352 v8::HandleScope scope; |
| 3296 DebugLocalContext env; | 3353 DebugLocalContext env; |
| 3297 | 3354 |
| 3298 // Register a debug event listener which steps and counts. | 3355 // Register a debug event listener which steps and counts. |
| 3299 v8::Debug::SetDebugEventListener(DebugEventStep); | 3356 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3300 | 3357 |
| 3301 // Create a function for testing stepping. | 3358 // Create a function for testing stepping. Run it to allow it to get |
| 3359 // optimized. |
| 3302 const char* src = "function foo(x) { " | 3360 const char* src = "function foo(x) { " |
| 3303 " var a = {};" | 3361 " var a = {};" |
| 3304 " with (a) {}" | 3362 " with (a) {}" |
| 3305 " with (b) {}" | 3363 " with (b) {}" |
| 3306 "}"; | 3364 "}" |
| 3365 "foo()"; |
| 3307 env->Global()->Set(v8::String::New("b"), v8::Object::New()); | 3366 env->Global()->Set(v8::String::New("b"), v8::Object::New()); |
| 3308 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3367 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3309 v8::Handle<v8::Value> result; | 3368 v8::Handle<v8::Value> result; |
| 3310 SetBreakPoint(foo, 8); // "var a = {};" | 3369 SetBreakPoint(foo, 8); // "var a = {};" |
| 3311 | 3370 |
| 3312 step_action = StepIn; | 3371 step_action = StepIn; |
| 3313 break_point_hit_count = 0; | 3372 break_point_hit_count = 0; |
| 3314 foo->Call(env->Global(), 0, NULL); | 3373 foo->Call(env->Global(), 0, NULL); |
| 3315 CHECK_EQ(4, break_point_hit_count); | 3374 CHECK_EQ(4, break_point_hit_count); |
| 3316 | 3375 |
| 3317 // Get rid of the debug event listener. | 3376 // Get rid of the debug event listener. |
| 3318 v8::Debug::SetDebugEventListener(NULL); | 3377 v8::Debug::SetDebugEventListener(NULL); |
| 3319 CheckDebuggerUnloaded(); | 3378 CheckDebuggerUnloaded(); |
| 3320 } | 3379 } |
| 3321 | 3380 |
| 3322 | 3381 |
| 3323 TEST(DebugConditional) { | 3382 TEST(DebugConditional) { |
| 3324 v8::HandleScope scope; | 3383 v8::HandleScope scope; |
| 3325 DebugLocalContext env; | 3384 DebugLocalContext env; |
| 3326 | 3385 |
| 3327 // Register a debug event listener which steps and counts. | 3386 // Register a debug event listener which steps and counts. |
| 3328 v8::Debug::SetDebugEventListener(DebugEventStep); | 3387 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3329 | 3388 |
| 3330 // Create a function for testing stepping. | 3389 // Create a function for testing stepping. Run it to allow it to get |
| 3390 // optimized. |
| 3331 const char* src = "function foo(x) { " | 3391 const char* src = "function foo(x) { " |
| 3332 " var a;" | 3392 " var a;" |
| 3333 " a = x ? 1 : 2;" | 3393 " a = x ? 1 : 2;" |
| 3334 " return a;" | 3394 " return a;" |
| 3335 "}"; | 3395 "}" |
| 3396 "foo()"; |
| 3336 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3397 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3337 SetBreakPoint(foo, 0); // "var a;" | 3398 SetBreakPoint(foo, 0); // "var a;" |
| 3338 | 3399 |
| 3339 step_action = StepIn; | 3400 step_action = StepIn; |
| 3340 break_point_hit_count = 0; | 3401 break_point_hit_count = 0; |
| 3341 foo->Call(env->Global(), 0, NULL); | 3402 foo->Call(env->Global(), 0, NULL); |
| 3342 CHECK_EQ(5, break_point_hit_count); | 3403 CHECK_EQ(5, break_point_hit_count); |
| 3343 | 3404 |
| 3344 step_action = StepIn; | 3405 step_action = StepIn; |
| 3345 break_point_hit_count = 0; | 3406 break_point_hit_count = 0; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3359 DebugLocalContext env; | 3420 DebugLocalContext env; |
| 3360 | 3421 |
| 3361 // Create a function for checking the function when hitting a break point. | 3422 // Create a function for checking the function when hitting a break point. |
| 3362 frame_function_name = CompileFunction(&env, | 3423 frame_function_name = CompileFunction(&env, |
| 3363 frame_function_name_source, | 3424 frame_function_name_source, |
| 3364 "frame_function_name"); | 3425 "frame_function_name"); |
| 3365 | 3426 |
| 3366 // Register a debug event listener which steps and counts. | 3427 // Register a debug event listener which steps and counts. |
| 3367 v8::Debug::SetDebugEventListener(DebugEventStepSequence); | 3428 v8::Debug::SetDebugEventListener(DebugEventStepSequence); |
| 3368 | 3429 |
| 3369 // Create functions for testing stepping. | 3430 // Create a function for testing stepping. Run it to allow it to get |
| 3431 // optimized. |
| 3370 const char* src = "function a() {b();c();}; " | 3432 const char* src = "function a() {b();c();}; " |
| 3371 "function b() {c();}; " | 3433 "function b() {c();}; " |
| 3372 "function c() {}; "; | 3434 "function c() {}; " |
| 3435 "a(); b(); c()"; |
| 3373 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); | 3436 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); |
| 3374 SetBreakPoint(a, 0); | 3437 SetBreakPoint(a, 0); |
| 3375 | 3438 |
| 3376 // Step through invocation of a with step in. | 3439 // Step through invocation of a with step in. |
| 3377 step_action = StepIn; | 3440 step_action = StepIn; |
| 3378 break_point_hit_count = 0; | 3441 break_point_hit_count = 0; |
| 3379 expected_step_sequence = "abcbaca"; | 3442 expected_step_sequence = "abcbaca"; |
| 3380 a->Call(env->Global(), 0, NULL); | 3443 a->Call(env->Global(), 0, NULL); |
| 3381 CHECK_EQ(StrLength(expected_step_sequence), | 3444 CHECK_EQ(StrLength(expected_step_sequence), |
| 3382 break_point_hit_count); | 3445 break_point_hit_count); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3408 DebugLocalContext env; | 3471 DebugLocalContext env; |
| 3409 | 3472 |
| 3410 // Create a function for checking the function when hitting a break point. | 3473 // Create a function for checking the function when hitting a break point. |
| 3411 frame_function_name = CompileFunction(&env, | 3474 frame_function_name = CompileFunction(&env, |
| 3412 frame_function_name_source, | 3475 frame_function_name_source, |
| 3413 "frame_function_name"); | 3476 "frame_function_name"); |
| 3414 | 3477 |
| 3415 // Register a debug event listener which steps and counts. | 3478 // Register a debug event listener which steps and counts. |
| 3416 v8::Debug::SetDebugEventListener(DebugEventStepSequence); | 3479 v8::Debug::SetDebugEventListener(DebugEventStepSequence); |
| 3417 | 3480 |
| 3418 // Create functions for testing stepping. | 3481 // Create a function for testing stepping. Run it to allow it to get |
| 3482 // optimized. |
| 3419 const char* src = "function a() {b(c(d()),d());c(d());d()}; " | 3483 const char* src = "function a() {b(c(d()),d());c(d());d()}; " |
| 3420 "function b(x,y) {c();}; " | 3484 "function b(x,y) {c();}; " |
| 3421 "function c(x) {}; " | 3485 "function c(x) {}; " |
| 3422 "function d() {}; "; | 3486 "function d() {}; " |
| 3487 "a(); b(); c(); d()"; |
| 3423 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); | 3488 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); |
| 3424 SetBreakPoint(a, 0); | 3489 SetBreakPoint(a, 0); |
| 3425 | 3490 |
| 3426 // Step through invocation of a with step in. | 3491 // Step through invocation of a with step in. |
| 3427 step_action = StepIn; | 3492 step_action = StepIn; |
| 3428 break_point_hit_count = 0; | 3493 break_point_hit_count = 0; |
| 3429 expected_step_sequence = "adacadabcbadacada"; | 3494 expected_step_sequence = "adacadabcbadacada"; |
| 3430 a->Call(env->Global(), 0, NULL); | 3495 a->Call(env->Global(), 0, NULL); |
| 3431 CHECK_EQ(StrLength(expected_step_sequence), | 3496 CHECK_EQ(StrLength(expected_step_sequence), |
| 3432 break_point_hit_count); | 3497 break_point_hit_count); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3458 DebugLocalContext env; | 3523 DebugLocalContext env; |
| 3459 | 3524 |
| 3460 // Create a function for checking the function when hitting a break point. | 3525 // Create a function for checking the function when hitting a break point. |
| 3461 frame_function_name = CompileFunction(&env, | 3526 frame_function_name = CompileFunction(&env, |
| 3462 frame_function_name_source, | 3527 frame_function_name_source, |
| 3463 "frame_function_name"); | 3528 "frame_function_name"); |
| 3464 | 3529 |
| 3465 // Register a debug event listener which steps and counts. | 3530 // Register a debug event listener which steps and counts. |
| 3466 v8::Debug::SetDebugEventListener(DebugEventStepSequence); | 3531 v8::Debug::SetDebugEventListener(DebugEventStepSequence); |
| 3467 | 3532 |
| 3468 // Create functions for testing stepping. | 3533 // Create a function for testing stepping. Run it to allow it to get |
| 3534 // optimized. |
| 3469 const char* src = "function a() {b(false);c();}; " | 3535 const char* src = "function a() {b(false);c();}; " |
| 3470 "function b(x) {if(x){c();};}; " | 3536 "function b(x) {if(x){c();};}; " |
| 3471 "function c() {}; "; | 3537 "function c() {}; " |
| 3538 "a(); b(); c()"; |
| 3472 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); | 3539 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); |
| 3473 SetBreakPoint(a, 0); | 3540 SetBreakPoint(a, 0); |
| 3474 | 3541 |
| 3475 // Step through invocation of a. | 3542 // Step through invocation of a. |
| 3476 step_action = StepIn; | 3543 step_action = StepIn; |
| 3477 break_point_hit_count = 0; | 3544 break_point_hit_count = 0; |
| 3478 expected_step_sequence = "abbaca"; | 3545 expected_step_sequence = "abbaca"; |
| 3479 a->Call(env->Global(), 0, NULL); | 3546 a->Call(env->Global(), 0, NULL); |
| 3480 CHECK_EQ(StrLength(expected_step_sequence), | 3547 CHECK_EQ(StrLength(expected_step_sequence), |
| 3481 break_point_hit_count); | 3548 break_point_hit_count); |
| (...skipping 2675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6157 v8::Handle<v8::Object> exec_state, | 6224 v8::Handle<v8::Object> exec_state, |
| 6158 v8::Handle<v8::Object> event_data, | 6225 v8::Handle<v8::Object> event_data, |
| 6159 v8::Handle<v8::Value> data) { | 6226 v8::Handle<v8::Value> data) { |
| 6160 | 6227 |
| 6161 if (event == v8::Break) { | 6228 if (event == v8::Break) { |
| 6162 break_point_hit_count++; | 6229 break_point_hit_count++; |
| 6163 | 6230 |
| 6164 // Get the name of the top frame function. | 6231 // Get the name of the top frame function. |
| 6165 if (!frame_function_name.IsEmpty()) { | 6232 if (!frame_function_name.IsEmpty()) { |
| 6166 // Get the name of the function. | 6233 // Get the name of the function. |
| 6167 const int argc = 1; | 6234 const int argc = 2; |
| 6168 v8::Handle<v8::Value> argv[argc] = { exec_state }; | 6235 v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; |
| 6169 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, | 6236 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, |
| 6170 argc, argv); | 6237 argc, argv); |
| 6171 if (result->IsUndefined()) { | 6238 if (result->IsUndefined()) { |
| 6172 last_function_hit[0] = '\0'; | 6239 last_function_hit[0] = '\0'; |
| 6173 } else { | 6240 } else { |
| 6174 CHECK(result->IsString()); | 6241 CHECK(result->IsString()); |
| 6175 v8::Handle<v8::String> function_name(result->ToString()); | 6242 v8::Handle<v8::String> function_name(result->ToString()); |
| 6176 function_name->WriteAscii(last_function_hit); | 6243 function_name->WriteAscii(last_function_hit); |
| 6177 } | 6244 } |
| 6178 } | 6245 } |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6891 static bool was_debug_event_called; | 6958 static bool was_debug_event_called; |
| 6892 static void DebugEventBreakDataChecker(const v8::Debug::EventDetails& details) { | 6959 static void DebugEventBreakDataChecker(const v8::Debug::EventDetails& details) { |
| 6893 if (details.GetEvent() == v8::BreakForCommand) { | 6960 if (details.GetEvent() == v8::BreakForCommand) { |
| 6894 CHECK_EQ(expected_break_data, details.GetClientData()); | 6961 CHECK_EQ(expected_break_data, details.GetClientData()); |
| 6895 was_debug_event_called = true; | 6962 was_debug_event_called = true; |
| 6896 } else if (details.GetEvent() == v8::Break) { | 6963 } else if (details.GetEvent() == v8::Break) { |
| 6897 was_debug_break_called = true; | 6964 was_debug_break_called = true; |
| 6898 } | 6965 } |
| 6899 } | 6966 } |
| 6900 | 6967 |
| 6968 |
| 6901 // Check that event details contain context where debug event occured. | 6969 // Check that event details contain context where debug event occured. |
| 6902 TEST(DebugEventBreakData) { | 6970 TEST(DebugEventBreakData) { |
| 6903 v8::HandleScope scope; | 6971 v8::HandleScope scope; |
| 6904 DebugLocalContext env; | 6972 DebugLocalContext env; |
| 6905 v8::Debug::SetDebugEventListener2(DebugEventBreakDataChecker); | 6973 v8::Debug::SetDebugEventListener2(DebugEventBreakDataChecker); |
| 6906 | 6974 |
| 6907 TestClientData::constructor_call_counter = 0; | 6975 TestClientData::constructor_call_counter = 0; |
| 6908 TestClientData::destructor_call_counter = 0; | 6976 TestClientData::destructor_call_counter = 0; |
| 6909 | 6977 |
| 6910 expected_break_data = NULL; | 6978 expected_break_data = NULL; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6943 CHECK(was_debug_break_called); | 7011 CHECK(was_debug_break_called); |
| 6944 | 7012 |
| 6945 CHECK_EQ(2, TestClientData::constructor_call_counter); | 7013 CHECK_EQ(2, TestClientData::constructor_call_counter); |
| 6946 CHECK_EQ(TestClientData::constructor_call_counter, | 7014 CHECK_EQ(TestClientData::constructor_call_counter, |
| 6947 TestClientData::destructor_call_counter); | 7015 TestClientData::destructor_call_counter); |
| 6948 | 7016 |
| 6949 v8::Debug::SetDebugEventListener(NULL); | 7017 v8::Debug::SetDebugEventListener(NULL); |
| 6950 CheckDebuggerUnloaded(); | 7018 CheckDebuggerUnloaded(); |
| 6951 } | 7019 } |
| 6952 | 7020 |
| 7021 static bool debug_event_break_deoptimize_done = false; |
| 7022 |
| 7023 static void DebugEventBreakDeoptimize(v8::DebugEvent event, |
| 7024 v8::Handle<v8::Object> exec_state, |
| 7025 v8::Handle<v8::Object> event_data, |
| 7026 v8::Handle<v8::Value> data) { |
| 7027 if (event == v8::Break) { |
| 7028 if (!frame_function_name.IsEmpty()) { |
| 7029 // Get the name of the function. |
| 7030 const int argc = 2; |
| 7031 v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; |
| 7032 v8::Handle<v8::Value> result = |
| 7033 frame_function_name->Call(exec_state, argc, argv); |
| 7034 if (!result->IsUndefined()) { |
| 7035 char fn[80]; |
| 7036 CHECK(result->IsString()); |
| 7037 v8::Handle<v8::String> function_name(result->ToString()); |
| 7038 function_name->WriteAscii(fn); |
| 7039 if (strcmp(fn, "bar") == 0) { |
| 7040 i::Deoptimizer::DeoptimizeAll(); |
| 7041 debug_event_break_deoptimize_done = true; |
| 7042 } |
| 7043 } |
| 7044 } |
| 7045 |
| 7046 v8::Debug::DebugBreak(); |
| 7047 } |
| 7048 } |
| 7049 |
| 7050 |
| 7051 // Test deoptimization when execution is broken using the debug break stack |
| 7052 // check interrupt. |
| 7053 TEST(DeoptimizeDuringDebugBreak) { |
| 7054 v8::HandleScope scope; |
| 7055 DebugLocalContext env; |
| 7056 env.ExposeDebug(); |
| 7057 |
| 7058 // Create a function for checking the function when hitting a break point. |
| 7059 frame_function_name = CompileFunction(&env, |
| 7060 frame_function_name_source, |
| 7061 "frame_function_name"); |
| 7062 |
| 7063 |
| 7064 // Set a debug event listener which will keep interrupting execution until |
| 7065 // debug break. When inside function bar it will deoptimize all functions. |
| 7066 // This tests lazy deoptimization bailout for the stack check, as the first |
| 7067 // time in function bar when using debug break and no break points will be at |
| 7068 // the initial stack check. |
| 7069 v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize, |
| 7070 v8::Undefined()); |
| 7071 |
| 7072 // Compile and run function bar which will optimize it for some flag settings. |
| 7073 v8::Script::Compile(v8::String::New("function bar(){}; bar()"))->Run(); |
| 7074 |
| 7075 // Set debug break and call bar again. |
| 7076 v8::Debug::DebugBreak(); |
| 7077 v8::Script::Compile(v8::String::New("bar()"))->Run(); |
| 7078 |
| 7079 CHECK(debug_event_break_deoptimize_done); |
| 7080 |
| 7081 v8::Debug::SetDebugEventListener(NULL); |
| 7082 } |
| 7083 |
| 7084 |
| 7085 static void DebugEventBreakWithOptimizedStack(v8::DebugEvent event, |
| 7086 v8::Handle<v8::Object> exec_state, |
| 7087 v8::Handle<v8::Object> event_data, |
| 7088 v8::Handle<v8::Value> data) { |
| 7089 if (event == v8::Break) { |
| 7090 if (!frame_function_name.IsEmpty()) { |
| 7091 for (int i = 0; i < 2; i++) { |
| 7092 const int argc = 2; |
| 7093 v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(i) }; |
| 7094 // Get the name of the function in frame i. |
| 7095 v8::Handle<v8::Value> result = |
| 7096 frame_function_name->Call(exec_state, argc, argv); |
| 7097 CHECK(result->IsString()); |
| 7098 v8::Handle<v8::String> function_name(result->ToString()); |
| 7099 CHECK(function_name->Equals(v8::String::New("loop"))); |
| 7100 // Get the name of the first argument in frame i. |
| 7101 result = frame_argument_name->Call(exec_state, argc, argv); |
| 7102 CHECK(result->IsString()); |
| 7103 v8::Handle<v8::String> argument_name(result->ToString()); |
| 7104 CHECK(argument_name->Equals(v8::String::New("count"))); |
| 7105 // Get the value of the first argument in frame i. If the |
| 7106 // funtion is optimized the value will be undefined, otherwise |
| 7107 // the value will be '1 - i'. |
| 7108 // |
| 7109 // TODO(3141533): We should be able to get the real value for |
| 7110 // optimized frames. |
| 7111 result = frame_argument_value->Call(exec_state, argc, argv); |
| 7112 CHECK(result->IsUndefined() || (result->Int32Value() == 1 - i)); |
| 7113 // Get the name of the first local variable. |
| 7114 result = frame_local_name->Call(exec_state, argc, argv); |
| 7115 CHECK(result->IsString()); |
| 7116 v8::Handle<v8::String> local_name(result->ToString()); |
| 7117 CHECK(local_name->Equals(v8::String::New("local"))); |
| 7118 // Get the value of the first local variable. If the function |
| 7119 // is optimized the value will be undefined, otherwise it will |
| 7120 // be 42. |
| 7121 // |
| 7122 // TODO(3141533): We should be able to get the real value for |
| 7123 // optimized frames. |
| 7124 result = frame_local_value->Call(exec_state, argc, argv); |
| 7125 CHECK(result->IsUndefined() || (result->Int32Value() == 42)); |
| 7126 } |
| 7127 } |
| 7128 } |
| 7129 } |
| 7130 |
| 7131 |
| 7132 static v8::Handle<v8::Value> ScheduleBreak(const v8::Arguments& args) { |
| 7133 v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack, |
| 7134 v8::Undefined()); |
| 7135 v8::Debug::DebugBreak(); |
| 7136 return v8::Undefined(); |
| 7137 } |
| 7138 |
| 7139 |
| 7140 TEST(DebugBreakStackInspection) { |
| 7141 v8::HandleScope scope; |
| 7142 DebugLocalContext env; |
| 7143 |
| 7144 frame_function_name = |
| 7145 CompileFunction(&env, frame_function_name_source, "frame_function_name"); |
| 7146 frame_argument_name = |
| 7147 CompileFunction(&env, frame_argument_name_source, "frame_argument_name"); |
| 7148 frame_argument_value = CompileFunction(&env, |
| 7149 frame_argument_value_source, |
| 7150 "frame_argument_value"); |
| 7151 frame_local_name = |
| 7152 CompileFunction(&env, frame_local_name_source, "frame_local_name"); |
| 7153 frame_local_value = |
| 7154 CompileFunction(&env, frame_local_value_source, "frame_local_value"); |
| 7155 |
| 7156 v8::Handle<v8::FunctionTemplate> schedule_break_template = |
| 7157 v8::FunctionTemplate::New(ScheduleBreak); |
| 7158 v8::Handle<v8::Function> schedule_break = |
| 7159 schedule_break_template->GetFunction(); |
| 7160 env->Global()->Set(v8_str("scheduleBreak"), schedule_break); |
| 7161 |
| 7162 const char* src = |
| 7163 "function loop(count) {" |
| 7164 " var local = 42;" |
| 7165 " if (count < 1) { scheduleBreak(); loop(count + 1); }" |
| 7166 "}" |
| 7167 "loop(0);"; |
| 7168 v8::Script::Compile(v8::String::New(src))->Run(); |
| 7169 } |
| 7170 |
| 6953 | 7171 |
| 6954 // Test that setting the terminate execution flag during debug break processing. | 7172 // Test that setting the terminate execution flag during debug break processing. |
| 6955 static void TestDebugBreakInLoop(const char* loop_head, | 7173 static void TestDebugBreakInLoop(const char* loop_head, |
| 6956 const char** loop_bodies, | 7174 const char** loop_bodies, |
| 6957 const char* loop_tail) { | 7175 const char* loop_tail) { |
| 6958 // Receive 100 breaks for each test and then terminate JavaScript execution. | 7176 // Receive 100 breaks for each test and then terminate JavaScript execution. |
| 6959 static int count = 0; | 7177 static int count = 0; |
| 6960 | 7178 |
| 6961 for (int i = 0; loop_bodies[i] != NULL; i++) { | 7179 for (int i = 0; loop_bodies[i] != NULL; i++) { |
| 6962 count++; | 7180 count++; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7018 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); | 7236 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); |
| 7019 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); | 7237 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); |
| 7020 | 7238 |
| 7021 // Get rid of the debug event listener. | 7239 // Get rid of the debug event listener. |
| 7022 v8::Debug::SetDebugEventListener(NULL); | 7240 v8::Debug::SetDebugEventListener(NULL); |
| 7023 CheckDebuggerUnloaded(); | 7241 CheckDebuggerUnloaded(); |
| 7024 } | 7242 } |
| 7025 | 7243 |
| 7026 | 7244 |
| 7027 #endif // ENABLE_DEBUGGER_SUPPORT | 7245 #endif // ENABLE_DEBUGGER_SUPPORT |
| OLD | NEW |