| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 ScopedVector<char> data(s->Utf8Length() + 1); | 79 ScopedVector<char> data(s->Utf8Length() + 1); |
| 80 if (data.start() == NULL) { | 80 if (data.start() == NULL) { |
| 81 V8::FatalProcessOutOfMemory("PrintLn"); | 81 V8::FatalProcessOutOfMemory("PrintLn"); |
| 82 return; | 82 return; |
| 83 } | 83 } |
| 84 s->WriteUtf8(data.start()); | 84 s->WriteUtf8(data.start()); |
| 85 PrintF("%s\n", data.start()); | 85 PrintF("%s\n", data.start()); |
| 86 } | 86 } |
| 87 | 87 |
| 88 | 88 |
| 89 static Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind) { | 89 static Handle<Code> ComputeCallDebugPrepareStepIn(Isolate* isolate, |
| 90 Isolate* isolate = Isolate::Current(); | 90 int argc, |
| 91 Code::Kind kind) { |
| 91 return isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind); | 92 return isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind); |
| 92 } | 93 } |
| 93 | 94 |
| 94 | 95 |
| 95 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { | 96 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { |
| 96 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); | 97 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); |
| 97 // Isolate::context() may have been NULL when "script collected" event | 98 // Isolate::context() may have been NULL when "script collected" event |
| 98 // occured. | 99 // occured. |
| 99 if (context.is_null()) return v8::Local<v8::Context>(); | 100 if (context.is_null()) return v8::Local<v8::Context>(); |
| 100 Handle<Context> native_context(context->native_context()); | 101 Handle<Context> native_context(context->native_context()); |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 // construct call or CallFunction stub call. | 427 // construct call or CallFunction stub call. |
| 427 Address target = rinfo()->target_address(); | 428 Address target = rinfo()->target_address(); |
| 428 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); | 429 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); |
| 429 if (target_code->is_call_stub() || target_code->is_keyed_call_stub()) { | 430 if (target_code->is_call_stub() || target_code->is_keyed_call_stub()) { |
| 430 // Step in through IC call is handled by the runtime system. Therefore make | 431 // Step in through IC call is handled by the runtime system. Therefore make |
| 431 // sure that the any current IC is cleared and the runtime system is | 432 // sure that the any current IC is cleared and the runtime system is |
| 432 // called. If the executing code has a debug break at the location change | 433 // called. If the executing code has a debug break at the location change |
| 433 // the call in the original code as it is the code there that will be | 434 // the call in the original code as it is the code there that will be |
| 434 // executed in place of the debug break call. | 435 // executed in place of the debug break call. |
| 435 Handle<Code> stub = ComputeCallDebugPrepareStepIn( | 436 Handle<Code> stub = ComputeCallDebugPrepareStepIn( |
| 436 target_code->arguments_count(), target_code->kind()); | 437 isolate, target_code->arguments_count(), target_code->kind()); |
| 437 if (IsDebugBreak()) { | 438 if (IsDebugBreak()) { |
| 438 original_rinfo()->set_target_address(stub->entry()); | 439 original_rinfo()->set_target_address(stub->entry()); |
| 439 } else { | 440 } else { |
| 440 rinfo()->set_target_address(stub->entry()); | 441 rinfo()->set_target_address(stub->entry()); |
| 441 } | 442 } |
| 442 } else { | 443 } else { |
| 443 #ifdef DEBUG | 444 #ifdef DEBUG |
| 444 // All the following stuff is needed only for assertion checks so the code | 445 // All the following stuff is needed only for assertion checks so the code |
| 445 // is wrapped in ifdef. | 446 // is wrapped in ifdef. |
| 446 Handle<Code> maybe_call_function_stub = target_code; | 447 Handle<Code> maybe_call_function_stub = target_code; |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 Smi::FromInt(StackFrame::INTERNAL); | 627 Smi::FromInt(StackFrame::INTERNAL); |
| 627 | 628 |
| 628 return reinterpret_cast<Object**>(&Memory::Object_at( | 629 return reinterpret_cast<Object**>(&Memory::Object_at( |
| 629 fp + StandardFrameConstants::kContextOffset)); | 630 fp + StandardFrameConstants::kContextOffset)); |
| 630 } | 631 } |
| 631 | 632 |
| 632 const int Debug::kFrameDropperFrameSize = 4; | 633 const int Debug::kFrameDropperFrameSize = 4; |
| 633 | 634 |
| 634 | 635 |
| 635 void ScriptCache::Add(Handle<Script> script) { | 636 void ScriptCache::Add(Handle<Script> script) { |
| 636 GlobalHandles* global_handles = Isolate::Current()->global_handles(); | 637 GlobalHandles* global_handles = isolate_->global_handles(); |
| 637 // Create an entry in the hash map for the script. | 638 // Create an entry in the hash map for the script. |
| 638 int id = script->id()->value(); | 639 int id = script->id()->value(); |
| 639 HashMap::Entry* entry = | 640 HashMap::Entry* entry = |
| 640 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); | 641 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); |
| 641 if (entry->value != NULL) { | 642 if (entry->value != NULL) { |
| 642 ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); | 643 ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); |
| 643 return; | 644 return; |
| 644 } | 645 } |
| 645 // Globalize the script object, make it weak and use the location of the | 646 // Globalize the script object, make it weak and use the location of the |
| 646 // global handle as the value in the hash map. | 647 // global handle as the value in the hash map. |
| 647 Handle<Script> script_ = | 648 Handle<Script> script_ = |
| 648 Handle<Script>::cast( | 649 Handle<Script>::cast( |
| 649 (global_handles->Create(*script))); | 650 (global_handles->Create(*script))); |
| 650 global_handles->MakeWeak(reinterpret_cast<Object**>(script_.location()), | 651 global_handles->MakeWeak(reinterpret_cast<Object**>(script_.location()), |
| 651 this, | 652 this, |
| 652 ScriptCache::HandleWeakScript); | 653 ScriptCache::HandleWeakScript); |
| 653 entry->value = script_.location(); | 654 entry->value = script_.location(); |
| 654 } | 655 } |
| 655 | 656 |
| 656 | 657 |
| 657 Handle<FixedArray> ScriptCache::GetScripts() { | 658 Handle<FixedArray> ScriptCache::GetScripts() { |
| 658 Factory* factory = Isolate::Current()->factory(); | 659 Factory* factory = isolate_->factory(); |
| 659 Handle<FixedArray> instances = factory->NewFixedArray(occupancy()); | 660 Handle<FixedArray> instances = factory->NewFixedArray(occupancy()); |
| 660 int count = 0; | 661 int count = 0; |
| 661 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { | 662 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
| 662 ASSERT(entry->value != NULL); | 663 ASSERT(entry->value != NULL); |
| 663 if (entry->value != NULL) { | 664 if (entry->value != NULL) { |
| 664 instances->set(count, *reinterpret_cast<Script**>(entry->value)); | 665 instances->set(count, *reinterpret_cast<Script**>(entry->value)); |
| 665 count++; | 666 count++; |
| 666 } | 667 } |
| 667 } | 668 } |
| 668 return instances; | 669 return instances; |
| 669 } | 670 } |
| 670 | 671 |
| 671 | 672 |
| 672 void ScriptCache::ProcessCollectedScripts() { | 673 void ScriptCache::ProcessCollectedScripts() { |
| 673 Debugger* debugger = Isolate::Current()->debugger(); | 674 Debugger* debugger = isolate_->debugger(); |
| 674 for (int i = 0; i < collected_scripts_.length(); i++) { | 675 for (int i = 0; i < collected_scripts_.length(); i++) { |
| 675 debugger->OnScriptCollected(collected_scripts_[i]); | 676 debugger->OnScriptCollected(collected_scripts_[i]); |
| 676 } | 677 } |
| 677 collected_scripts_.Clear(); | 678 collected_scripts_.Clear(); |
| 678 } | 679 } |
| 679 | 680 |
| 680 | 681 |
| 681 void ScriptCache::Clear() { | 682 void ScriptCache::Clear() { |
| 682 GlobalHandles* global_handles = Isolate::Current()->global_handles(); | 683 GlobalHandles* global_handles = isolate_->global_handles(); |
| 683 // Iterate the script cache to get rid of all the weak handles. | 684 // Iterate the script cache to get rid of all the weak handles. |
| 684 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { | 685 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
| 685 ASSERT(entry != NULL); | 686 ASSERT(entry != NULL); |
| 686 Object** location = reinterpret_cast<Object**>(entry->value); | 687 Object** location = reinterpret_cast<Object**>(entry->value); |
| 687 ASSERT((*location)->IsScript()); | 688 ASSERT((*location)->IsScript()); |
| 688 global_handles->ClearWeakness(location); | 689 global_handles->ClearWeakness(location); |
| 689 global_handles->Destroy(location); | 690 global_handles->Destroy(location); |
| 690 } | 691 } |
| 691 // Clear the content of the hash map. | 692 // Clear the content of the hash map. |
| 692 HashMap::Clear(); | 693 HashMap::Clear(); |
| 693 } | 694 } |
| 694 | 695 |
| 695 | 696 |
| 696 void ScriptCache::HandleWeakScript(v8::Isolate* isolate, | 697 void ScriptCache::HandleWeakScript(v8::Isolate* isolate, |
| 697 v8::Persistent<v8::Value>* obj, | 698 v8::Persistent<v8::Value>* obj, |
| 698 void* data) { | 699 void* data) { |
| 699 ScriptCache* script_cache = reinterpret_cast<ScriptCache*>(data); | 700 ScriptCache* script_cache = reinterpret_cast<ScriptCache*>(data); |
| 700 // Find the location of the global handle. | 701 // Find the location of the global handle. |
| 701 Script** location = | 702 Script** location = |
| 702 reinterpret_cast<Script**>(Utils::OpenPersistent(*obj).location()); | 703 reinterpret_cast<Script**>(Utils::OpenPersistent(*obj).location()); |
| 703 ASSERT((*location)->IsScript()); | 704 ASSERT((*location)->IsScript()); |
| 704 | 705 |
| 705 // Remove the entry from the cache. | 706 // Remove the entry from the cache. |
| 706 int id = (*location)->id()->value(); | 707 int id = (*location)->id()->value(); |
| 707 script_cache->Remove(reinterpret_cast<void*>(id), Hash(id)); | 708 script_cache->Remove(reinterpret_cast<void*>(id), Hash(id)); |
| 708 script_cache->collected_scripts_.Add(id); | 709 script_cache->collected_scripts_.Add(id); |
| 709 | 710 |
| 710 // Clear the weak handle. | 711 // Clear the weak handle. |
| 711 obj->Dispose(isolate); | 712 obj->Dispose(); |
| 712 } | 713 } |
| 713 | 714 |
| 714 | 715 |
| 715 void Debug::SetUp(bool create_heap_objects) { | 716 void Debug::SetUp(bool create_heap_objects) { |
| 716 ThreadInit(); | 717 ThreadInit(); |
| 717 if (create_heap_objects) { | 718 if (create_heap_objects) { |
| 718 // Get code to handle debug break on return. | 719 // Get code to handle debug break on return. |
| 719 debug_break_return_ = | 720 debug_break_return_ = |
| 720 isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak); | 721 isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak); |
| 721 ASSERT(debug_break_return_->IsCode()); | 722 ASSERT(debug_break_return_->IsCode()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 743 node = debug->debug_info_list_; | 744 node = debug->debug_info_list_; |
| 744 while (node != NULL) { | 745 while (node != NULL) { |
| 745 ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data)); | 746 ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data)); |
| 746 node = node->next(); | 747 node = node->next(); |
| 747 } | 748 } |
| 748 #endif | 749 #endif |
| 749 } | 750 } |
| 750 | 751 |
| 751 | 752 |
| 752 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { | 753 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { |
| 753 GlobalHandles* global_handles = Isolate::Current()->global_handles(); | 754 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); |
| 754 // Globalize the request debug info object and make it weak. | 755 // Globalize the request debug info object and make it weak. |
| 755 debug_info_ = Handle<DebugInfo>::cast( | 756 debug_info_ = Handle<DebugInfo>::cast( |
| 756 (global_handles->Create(debug_info))); | 757 (global_handles->Create(debug_info))); |
| 757 global_handles->MakeWeak(reinterpret_cast<Object**>(debug_info_.location()), | 758 global_handles->MakeWeak(reinterpret_cast<Object**>(debug_info_.location()), |
| 758 this, | 759 this, |
| 759 Debug::HandleWeakDebugInfo); | 760 Debug::HandleWeakDebugInfo); |
| 760 } | 761 } |
| 761 | 762 |
| 762 | 763 |
| 763 DebugInfoListNode::~DebugInfoListNode() { | 764 DebugInfoListNode::~DebugInfoListNode() { |
| 764 Isolate::Current()->global_handles()->Destroy( | 765 debug_info_->GetIsolate()->global_handles()->Destroy( |
| 765 reinterpret_cast<Object**>(debug_info_.location())); | 766 reinterpret_cast<Object**>(debug_info_.location())); |
| 766 } | 767 } |
| 767 | 768 |
| 768 | 769 |
| 769 bool Debug::CompileDebuggerScript(int index) { | 770 bool Debug::CompileDebuggerScript(Isolate* isolate, int index) { |
| 770 Isolate* isolate = Isolate::Current(); | |
| 771 Factory* factory = isolate->factory(); | 771 Factory* factory = isolate->factory(); |
| 772 HandleScope scope(isolate); | 772 HandleScope scope(isolate); |
| 773 | 773 |
| 774 // Bail out if the index is invalid. | 774 // Bail out if the index is invalid. |
| 775 if (index == -1) { | 775 if (index == -1) { |
| 776 return false; | 776 return false; |
| 777 } | 777 } |
| 778 | 778 |
| 779 // Find source and name for the requested script. | 779 // Find source and name for the requested script. |
| 780 Handle<String> source_code = | 780 Handle<String> source_code = |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 if (caught_exception) { | 817 if (caught_exception) { |
| 818 ASSERT(!isolate->has_pending_exception()); | 818 ASSERT(!isolate->has_pending_exception()); |
| 819 MessageLocation computed_location; | 819 MessageLocation computed_location; |
| 820 isolate->ComputeLocation(&computed_location); | 820 isolate->ComputeLocation(&computed_location); |
| 821 Handle<Object> message = MessageHandler::MakeMessageObject( | 821 Handle<Object> message = MessageHandler::MakeMessageObject( |
| 822 isolate, "error_loading_debugger", &computed_location, | 822 isolate, "error_loading_debugger", &computed_location, |
| 823 Vector<Handle<Object> >::empty(), Handle<String>(), Handle<JSArray>()); | 823 Vector<Handle<Object> >::empty(), Handle<String>(), Handle<JSArray>()); |
| 824 ASSERT(!isolate->has_pending_exception()); | 824 ASSERT(!isolate->has_pending_exception()); |
| 825 if (!exception.is_null()) { | 825 if (!exception.is_null()) { |
| 826 isolate->set_pending_exception(*exception); | 826 isolate->set_pending_exception(*exception); |
| 827 MessageHandler::ReportMessage(Isolate::Current(), NULL, message); | 827 MessageHandler::ReportMessage(isolate, NULL, message); |
| 828 isolate->clear_pending_exception(); | 828 isolate->clear_pending_exception(); |
| 829 } | 829 } |
| 830 return false; | 830 return false; |
| 831 } | 831 } |
| 832 | 832 |
| 833 // Mark this script as native and return successfully. | 833 // Mark this script as native and return successfully. |
| 834 Handle<Script> script(Script::cast(function->shared()->script())); | 834 Handle<Script> script(Script::cast(function->shared()->script())); |
| 835 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 835 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
| 836 return true; | 836 return true; |
| 837 } | 837 } |
| 838 | 838 |
| 839 | 839 |
| 840 bool Debug::Load() { | 840 bool Debug::Load() { |
| 841 // Return if debugger is already loaded. | 841 // Return if debugger is already loaded. |
| 842 if (IsLoaded()) return true; | 842 if (IsLoaded()) return true; |
| 843 | 843 |
| 844 Debugger* debugger = isolate_->debugger(); | 844 Debugger* debugger = isolate_->debugger(); |
| 845 | 845 |
| 846 // Bail out if we're already in the process of compiling the native | 846 // Bail out if we're already in the process of compiling the native |
| 847 // JavaScript source code for the debugger. | 847 // JavaScript source code for the debugger. |
| 848 if (debugger->compiling_natives() || | 848 if (debugger->compiling_natives() || |
| 849 debugger->is_loading_debugger()) | 849 debugger->is_loading_debugger()) |
| 850 return false; | 850 return false; |
| 851 debugger->set_loading_debugger(true); | 851 debugger->set_loading_debugger(true); |
| 852 | 852 |
| 853 // Disable breakpoints and interrupts while compiling and running the | 853 // Disable breakpoints and interrupts while compiling and running the |
| 854 // debugger scripts including the context creation code. | 854 // debugger scripts including the context creation code. |
| 855 DisableBreak disable(true); | 855 DisableBreak disable(isolate_, true); |
| 856 PostponeInterruptsScope postpone(isolate_); | 856 PostponeInterruptsScope postpone(isolate_); |
| 857 | 857 |
| 858 // Create the debugger context. | 858 // Create the debugger context. |
| 859 HandleScope scope(isolate_); | 859 HandleScope scope(isolate_); |
| 860 Handle<Context> context = | 860 Handle<Context> context = |
| 861 isolate_->bootstrapper()->CreateEnvironment( | 861 isolate_->bootstrapper()->CreateEnvironment( |
| 862 Handle<Object>::null(), | 862 Handle<Object>::null(), |
| 863 v8::Handle<ObjectTemplate>(), | 863 v8::Handle<ObjectTemplate>(), |
| 864 NULL); | 864 NULL); |
| 865 | 865 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 879 JSReceiver::SetProperty(global, | 879 JSReceiver::SetProperty(global, |
| 880 key, | 880 key, |
| 881 Handle<Object>(global->builtins(), isolate_), | 881 Handle<Object>(global->builtins(), isolate_), |
| 882 NONE, | 882 NONE, |
| 883 kNonStrictMode), | 883 kNonStrictMode), |
| 884 false); | 884 false); |
| 885 | 885 |
| 886 // Compile the JavaScript for the debugger in the debugger context. | 886 // Compile the JavaScript for the debugger in the debugger context. |
| 887 debugger->set_compiling_natives(true); | 887 debugger->set_compiling_natives(true); |
| 888 bool caught_exception = | 888 bool caught_exception = |
| 889 !CompileDebuggerScript(Natives::GetIndex("mirror")) || | 889 !CompileDebuggerScript(isolate_, Natives::GetIndex("mirror")) || |
| 890 !CompileDebuggerScript(Natives::GetIndex("debug")); | 890 !CompileDebuggerScript(isolate_, Natives::GetIndex("debug")); |
| 891 | 891 |
| 892 if (FLAG_enable_liveedit) { | 892 if (FLAG_enable_liveedit) { |
| 893 caught_exception = caught_exception || | 893 caught_exception = caught_exception || |
| 894 !CompileDebuggerScript(Natives::GetIndex("liveedit")); | 894 !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit")); |
| 895 } | 895 } |
| 896 | 896 |
| 897 debugger->set_compiling_natives(false); | 897 debugger->set_compiling_natives(false); |
| 898 | 898 |
| 899 // Make sure we mark the debugger as not loading before we might | 899 // Make sure we mark the debugger as not loading before we might |
| 900 // return. | 900 // return. |
| 901 debugger->set_loading_debugger(false); | 901 debugger->set_loading_debugger(false); |
| 902 | 902 |
| 903 // Check for caught exceptions. | 903 // Check for caught exceptions. |
| 904 if (caught_exception) return false; | 904 if (caught_exception) return false; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 JavaScriptFrameIterator it(isolate_); | 951 JavaScriptFrameIterator it(isolate_); |
| 952 JavaScriptFrame* frame = it.frame(); | 952 JavaScriptFrame* frame = it.frame(); |
| 953 | 953 |
| 954 // Just continue if breaks are disabled or debugger cannot be loaded. | 954 // Just continue if breaks are disabled or debugger cannot be loaded. |
| 955 if (disable_break() || !Load()) { | 955 if (disable_break() || !Load()) { |
| 956 SetAfterBreakTarget(frame); | 956 SetAfterBreakTarget(frame); |
| 957 return heap->undefined_value(); | 957 return heap->undefined_value(); |
| 958 } | 958 } |
| 959 | 959 |
| 960 // Enter the debugger. | 960 // Enter the debugger. |
| 961 EnterDebugger debugger; | 961 EnterDebugger debugger(isolate_); |
| 962 if (debugger.FailedToEnter()) { | 962 if (debugger.FailedToEnter()) { |
| 963 return heap->undefined_value(); | 963 return heap->undefined_value(); |
| 964 } | 964 } |
| 965 | 965 |
| 966 // Postpone interrupt during breakpoint processing. | 966 // Postpone interrupt during breakpoint processing. |
| 967 PostponeInterruptsScope postpone(isolate_); | 967 PostponeInterruptsScope postpone(isolate_); |
| 968 | 968 |
| 969 // Get the debug info (create it if it does not exist). | 969 // Get the debug info (create it if it does not exist). |
| 970 Handle<SharedFunctionInfo> shared = | 970 Handle<SharedFunctionInfo> shared = |
| 971 Handle<SharedFunctionInfo>(frame->function()->shared()); | 971 Handle<SharedFunctionInfo>(frame->function()->shared()); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 // Clear all current stepping setup. | 1010 // Clear all current stepping setup. |
| 1011 ClearStepping(); | 1011 ClearStepping(); |
| 1012 | 1012 |
| 1013 if (thread_local_.queued_step_count_ > 0) { | 1013 if (thread_local_.queued_step_count_ > 0) { |
| 1014 // Perform queued steps | 1014 // Perform queued steps |
| 1015 int step_count = thread_local_.queued_step_count_; | 1015 int step_count = thread_local_.queued_step_count_; |
| 1016 | 1016 |
| 1017 // Clear queue | 1017 // Clear queue |
| 1018 thread_local_.queued_step_count_ = 0; | 1018 thread_local_.queued_step_count_ = 0; |
| 1019 | 1019 |
| 1020 PrepareStep(StepNext, step_count); | 1020 PrepareStep(StepNext, step_count, StackFrame::NO_ID); |
| 1021 } else { | 1021 } else { |
| 1022 // Notify the debug event listeners. | 1022 // Notify the debug event listeners. |
| 1023 isolate_->debugger()->OnDebugBreak(break_points_hit, false); | 1023 isolate_->debugger()->OnDebugBreak(break_points_hit, false); |
| 1024 } | 1024 } |
| 1025 } else if (thread_local_.last_step_action_ != StepNone) { | 1025 } else if (thread_local_.last_step_action_ != StepNone) { |
| 1026 // Hold on to last step action as it is cleared by the call to | 1026 // Hold on to last step action as it is cleared by the call to |
| 1027 // ClearStepping. | 1027 // ClearStepping. |
| 1028 StepAction step_action = thread_local_.last_step_action_; | 1028 StepAction step_action = thread_local_.last_step_action_; |
| 1029 int step_count = thread_local_.step_count_; | 1029 int step_count = thread_local_.step_count_; |
| 1030 | 1030 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1048 | 1048 |
| 1049 // Set up for StepOut to reach target frame. | 1049 // Set up for StepOut to reach target frame. |
| 1050 step_action = StepOut; | 1050 step_action = StepOut; |
| 1051 step_count = count; | 1051 step_count = count; |
| 1052 } | 1052 } |
| 1053 | 1053 |
| 1054 // Clear all current stepping setup. | 1054 // Clear all current stepping setup. |
| 1055 ClearStepping(); | 1055 ClearStepping(); |
| 1056 | 1056 |
| 1057 // Set up for the remaining steps. | 1057 // Set up for the remaining steps. |
| 1058 PrepareStep(step_action, step_count); | 1058 PrepareStep(step_action, step_count, StackFrame::NO_ID); |
| 1059 } | 1059 } |
| 1060 | 1060 |
| 1061 if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) { | 1061 if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) { |
| 1062 SetAfterBreakTarget(frame); | 1062 SetAfterBreakTarget(frame); |
| 1063 } else if (thread_local_.frame_drop_mode_ == | 1063 } else if (thread_local_.frame_drop_mode_ == |
| 1064 FRAME_DROPPED_IN_IC_CALL) { | 1064 FRAME_DROPPED_IN_IC_CALL) { |
| 1065 // We must have been calling IC stub. Do not go there anymore. | 1065 // We must have been calling IC stub. Do not go there anymore. |
| 1066 Code* plain_return = isolate_->builtins()->builtin( | 1066 Code* plain_return = isolate_->builtins()->builtin( |
| 1067 Builtins::kPlainReturn_LiveEdit); | 1067 Builtins::kPlainReturn_LiveEdit); |
| 1068 thread_local_.after_break_target_ = plain_return->entry(); | 1068 thread_local_.after_break_target_ = plain_return->entry(); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 | 1369 |
| 1370 bool Debug::IsBreakOnException(ExceptionBreakType type) { | 1370 bool Debug::IsBreakOnException(ExceptionBreakType type) { |
| 1371 if (type == BreakUncaughtException) { | 1371 if (type == BreakUncaughtException) { |
| 1372 return break_on_uncaught_exception_; | 1372 return break_on_uncaught_exception_; |
| 1373 } else { | 1373 } else { |
| 1374 return break_on_exception_; | 1374 return break_on_exception_; |
| 1375 } | 1375 } |
| 1376 } | 1376 } |
| 1377 | 1377 |
| 1378 | 1378 |
| 1379 void Debug::PrepareStep(StepAction step_action, int step_count) { | 1379 void Debug::PrepareStep(StepAction step_action, |
| 1380 int step_count, |
| 1381 StackFrame::Id frame_id) { |
| 1380 HandleScope scope(isolate_); | 1382 HandleScope scope(isolate_); |
| 1381 | 1383 |
| 1382 PrepareForBreakPoints(); | 1384 PrepareForBreakPoints(); |
| 1383 | 1385 |
| 1384 ASSERT(Debug::InDebugger()); | 1386 ASSERT(Debug::InDebugger()); |
| 1385 | 1387 |
| 1386 // Remember this step action and count. | 1388 // Remember this step action and count. |
| 1387 thread_local_.last_step_action_ = step_action; | 1389 thread_local_.last_step_action_ = step_action; |
| 1388 if (step_action == StepOut) { | 1390 if (step_action == StepOut) { |
| 1389 // For step out target frame will be found on the stack so there is no need | 1391 // For step out target frame will be found on the stack so there is no need |
| 1390 // to set step counter for it. It's expected to always be 0 for StepOut. | 1392 // to set step counter for it. It's expected to always be 0 for StepOut. |
| 1391 thread_local_.step_count_ = 0; | 1393 thread_local_.step_count_ = 0; |
| 1392 } else { | 1394 } else { |
| 1393 thread_local_.step_count_ = step_count; | 1395 thread_local_.step_count_ = step_count; |
| 1394 } | 1396 } |
| 1395 | 1397 |
| 1396 // Get the frame where the execution has stopped and skip the debug frame if | 1398 // Get the frame where the execution has stopped and skip the debug frame if |
| 1397 // any. The debug frame will only be present if execution was stopped due to | 1399 // any. The debug frame will only be present if execution was stopped due to |
| 1398 // hitting a break point. In other situations (e.g. unhandled exception) the | 1400 // hitting a break point. In other situations (e.g. unhandled exception) the |
| 1399 // debug frame is not present. | 1401 // debug frame is not present. |
| 1400 StackFrame::Id id = break_frame_id(); | 1402 StackFrame::Id id = break_frame_id(); |
| 1401 if (id == StackFrame::NO_ID) { | 1403 if (id == StackFrame::NO_ID) { |
| 1402 // If there is no JavaScript stack don't do anything. | 1404 // If there is no JavaScript stack don't do anything. |
| 1403 return; | 1405 return; |
| 1404 } | 1406 } |
| 1407 if (frame_id != StackFrame::NO_ID) { |
| 1408 id = frame_id; |
| 1409 } |
| 1405 JavaScriptFrameIterator frames_it(isolate_, id); | 1410 JavaScriptFrameIterator frames_it(isolate_, id); |
| 1406 JavaScriptFrame* frame = frames_it.frame(); | 1411 JavaScriptFrame* frame = frames_it.frame(); |
| 1407 | 1412 |
| 1408 // First of all ensure there is one-shot break points in the top handler | 1413 // First of all ensure there is one-shot break points in the top handler |
| 1409 // if any. | 1414 // if any. |
| 1410 FloodHandlerWithOneShot(); | 1415 FloodHandlerWithOneShot(); |
| 1411 | 1416 |
| 1412 // If the function on the top frame is unresolved perform step out. This will | 1417 // If the function on the top frame is unresolved perform step out. This will |
| 1413 // be the case when calling unknown functions and having the debugger stopped | 1418 // be the case when calling unknown functions and having the debugger stopped |
| 1414 // in an unhandled exception. | 1419 // in an unhandled exception. |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1642 // Check whether a code stub with the specified major key is a possible break | 1647 // Check whether a code stub with the specified major key is a possible break |
| 1643 // location. | 1648 // location. |
| 1644 bool Debug::IsBreakStub(Code* code) { | 1649 bool Debug::IsBreakStub(Code* code) { |
| 1645 CodeStub::Major major_key = CodeStub::GetMajorKey(code); | 1650 CodeStub::Major major_key = CodeStub::GetMajorKey(code); |
| 1646 return major_key == CodeStub::CallFunction; | 1651 return major_key == CodeStub::CallFunction; |
| 1647 } | 1652 } |
| 1648 | 1653 |
| 1649 | 1654 |
| 1650 // Find the builtin to use for invoking the debug break | 1655 // Find the builtin to use for invoking the debug break |
| 1651 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) { | 1656 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) { |
| 1652 Isolate* isolate = Isolate::Current(); | 1657 Isolate* isolate = code->GetIsolate(); |
| 1653 | 1658 |
| 1654 // Find the builtin debug break function matching the calling convention | 1659 // Find the builtin debug break function matching the calling convention |
| 1655 // used by the call site. | 1660 // used by the call site. |
| 1656 if (code->is_inline_cache_stub()) { | 1661 if (code->is_inline_cache_stub()) { |
| 1657 switch (code->kind()) { | 1662 switch (code->kind()) { |
| 1658 case Code::CALL_IC: | 1663 case Code::CALL_IC: |
| 1659 case Code::KEYED_CALL_IC: | 1664 case Code::KEYED_CALL_IC: |
| 1660 return isolate->stub_cache()->ComputeCallDebugBreak( | 1665 return isolate->stub_cache()->ComputeCallDebugBreak( |
| 1661 code->arguments_count(), code->kind()); | 1666 code->arguments_count(), code->kind()); |
| 1662 | 1667 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1697 | 1702 |
| 1698 UNREACHABLE(); | 1703 UNREACHABLE(); |
| 1699 return Handle<Code>::null(); | 1704 return Handle<Code>::null(); |
| 1700 } | 1705 } |
| 1701 | 1706 |
| 1702 | 1707 |
| 1703 // Simple function for returning the source positions for active break points. | 1708 // Simple function for returning the source positions for active break points. |
| 1704 Handle<Object> Debug::GetSourceBreakLocations( | 1709 Handle<Object> Debug::GetSourceBreakLocations( |
| 1705 Handle<SharedFunctionInfo> shared, | 1710 Handle<SharedFunctionInfo> shared, |
| 1706 BreakPositionAlignment position_alignment) { | 1711 BreakPositionAlignment position_alignment) { |
| 1707 Isolate* isolate = Isolate::Current(); | 1712 Isolate* isolate = shared->GetIsolate(); |
| 1708 Heap* heap = isolate->heap(); | 1713 Heap* heap = isolate->heap(); |
| 1709 if (!HasDebugInfo(shared)) { | 1714 if (!HasDebugInfo(shared)) { |
| 1710 return Handle<Object>(heap->undefined_value(), isolate); | 1715 return Handle<Object>(heap->undefined_value(), isolate); |
| 1711 } | 1716 } |
| 1712 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1717 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| 1713 if (debug_info->GetBreakPointCount() == 0) { | 1718 if (debug_info->GetBreakPointCount() == 0) { |
| 1714 return Handle<Object>(heap->undefined_value(), isolate); | 1719 return Handle<Object>(heap->undefined_value(), isolate); |
| 1715 } | 1720 } |
| 1716 Handle<FixedArray> locations = | 1721 Handle<FixedArray> locations = |
| 1717 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount()); | 1722 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount()); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1876 ASSERT(!current_code->has_debug_break_slots()); | 1881 ASSERT(!current_code->has_debug_break_slots()); |
| 1877 | 1882 |
| 1878 CompilationInfoWithZone info(function); | 1883 CompilationInfoWithZone info(function); |
| 1879 info.MarkCompilingForDebugging(current_code); | 1884 info.MarkCompilingForDebugging(current_code); |
| 1880 ASSERT(!info.shared_info()->is_compiled()); | 1885 ASSERT(!info.shared_info()->is_compiled()); |
| 1881 ASSERT(!info.isolate()->has_pending_exception()); | 1886 ASSERT(!info.isolate()->has_pending_exception()); |
| 1882 | 1887 |
| 1883 // Use compile lazy which will end up compiling the full code in the | 1888 // Use compile lazy which will end up compiling the full code in the |
| 1884 // configuration configured above. | 1889 // configuration configured above. |
| 1885 bool result = Compiler::CompileLazy(&info); | 1890 bool result = Compiler::CompileLazy(&info); |
| 1886 ASSERT(result != Isolate::Current()->has_pending_exception()); | 1891 ASSERT(result != info.isolate()->has_pending_exception()); |
| 1887 info.isolate()->clear_pending_exception(); | 1892 info.isolate()->clear_pending_exception(); |
| 1888 #if DEBUG | 1893 #if DEBUG |
| 1889 if (result) { | 1894 if (result) { |
| 1890 Handle<Code> new_code(function->shared()->code()); | 1895 Handle<Code> new_code(function->shared()->code()); |
| 1891 ASSERT(new_code->has_debug_break_slots()); | 1896 ASSERT(new_code->has_debug_break_slots()); |
| 1892 ASSERT(current_code->is_compiled_optimizable() == | 1897 ASSERT(current_code->is_compiled_optimizable() == |
| 1893 new_code->is_compiled_optimizable()); | 1898 new_code->is_compiled_optimizable()); |
| 1894 } | 1899 } |
| 1895 #endif | 1900 #endif |
| 1896 return result; | 1901 return result; |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2530 | 2535 |
| 2531 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets | 2536 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets |
| 2532 // rid of all the cached script wrappers and the second gets rid of the | 2537 // rid of all the cached script wrappers and the second gets rid of the |
| 2533 // scripts which are no longer referenced. The second also sweeps precisely, | 2538 // scripts which are no longer referenced. The second also sweeps precisely, |
| 2534 // which saves us doing yet another GC to make the heap iterable. | 2539 // which saves us doing yet another GC to make the heap iterable. |
| 2535 heap->CollectAllGarbage(Heap::kNoGCFlags, "Debug::CreateScriptCache"); | 2540 heap->CollectAllGarbage(Heap::kNoGCFlags, "Debug::CreateScriptCache"); |
| 2536 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 2541 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
| 2537 "Debug::CreateScriptCache"); | 2542 "Debug::CreateScriptCache"); |
| 2538 | 2543 |
| 2539 ASSERT(script_cache_ == NULL); | 2544 ASSERT(script_cache_ == NULL); |
| 2540 script_cache_ = new ScriptCache(); | 2545 script_cache_ = new ScriptCache(isolate_); |
| 2541 | 2546 |
| 2542 // Scan heap for Script objects. | 2547 // Scan heap for Script objects. |
| 2543 int count = 0; | 2548 int count = 0; |
| 2544 HeapIterator iterator(heap); | 2549 HeapIterator iterator(heap); |
| 2545 DisallowHeapAllocation no_allocation; | 2550 DisallowHeapAllocation no_allocation; |
| 2546 | 2551 |
| 2547 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 2552 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 2548 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { | 2553 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { |
| 2549 script_cache_->Add(Handle<Script>(Script::cast(obj))); | 2554 script_cache_->Add(Handle<Script>(Script::cast(obj))); |
| 2550 count++; | 2555 count++; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2747 if (uncaught) { | 2752 if (uncaught) { |
| 2748 // Uncaught exceptions are reported by either flags. | 2753 // Uncaught exceptions are reported by either flags. |
| 2749 if (!(debug->break_on_uncaught_exception() || | 2754 if (!(debug->break_on_uncaught_exception() || |
| 2750 debug->break_on_exception())) return; | 2755 debug->break_on_exception())) return; |
| 2751 } else { | 2756 } else { |
| 2752 // Caught exceptions are reported is activated. | 2757 // Caught exceptions are reported is activated. |
| 2753 if (!debug->break_on_exception()) return; | 2758 if (!debug->break_on_exception()) return; |
| 2754 } | 2759 } |
| 2755 | 2760 |
| 2756 // Enter the debugger. | 2761 // Enter the debugger. |
| 2757 EnterDebugger debugger; | 2762 EnterDebugger debugger(isolate_); |
| 2758 if (debugger.FailedToEnter()) return; | 2763 if (debugger.FailedToEnter()) return; |
| 2759 | 2764 |
| 2760 // Clear all current stepping setup. | 2765 // Clear all current stepping setup. |
| 2761 debug->ClearStepping(); | 2766 debug->ClearStepping(); |
| 2762 // Create the event data object. | 2767 // Create the event data object. |
| 2763 bool caught_exception = false; | 2768 bool caught_exception = false; |
| 2764 Handle<Object> exec_state = MakeExecutionState(&caught_exception); | 2769 Handle<Object> exec_state = MakeExecutionState(&caught_exception); |
| 2765 Handle<Object> event_data; | 2770 Handle<Object> event_data; |
| 2766 if (!caught_exception) { | 2771 if (!caught_exception) { |
| 2767 event_data = MakeExceptionEvent(exec_state, exception, uncaught, | 2772 event_data = MakeExceptionEvent(exec_state, exception, uncaught, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2813 | 2818 |
| 2814 void Debugger::OnBeforeCompile(Handle<Script> script) { | 2819 void Debugger::OnBeforeCompile(Handle<Script> script) { |
| 2815 HandleScope scope(isolate_); | 2820 HandleScope scope(isolate_); |
| 2816 | 2821 |
| 2817 // Bail out based on state or if there is no listener for this event | 2822 // Bail out based on state or if there is no listener for this event |
| 2818 if (isolate_->debug()->InDebugger()) return; | 2823 if (isolate_->debug()->InDebugger()) return; |
| 2819 if (compiling_natives()) return; | 2824 if (compiling_natives()) return; |
| 2820 if (!EventActive(v8::BeforeCompile)) return; | 2825 if (!EventActive(v8::BeforeCompile)) return; |
| 2821 | 2826 |
| 2822 // Enter the debugger. | 2827 // Enter the debugger. |
| 2823 EnterDebugger debugger; | 2828 EnterDebugger debugger(isolate_); |
| 2824 if (debugger.FailedToEnter()) return; | 2829 if (debugger.FailedToEnter()) return; |
| 2825 | 2830 |
| 2826 // Create the event data object. | 2831 // Create the event data object. |
| 2827 bool caught_exception = false; | 2832 bool caught_exception = false; |
| 2828 Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception); | 2833 Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception); |
| 2829 // Bail out and don't call debugger if exception. | 2834 // Bail out and don't call debugger if exception. |
| 2830 if (caught_exception) { | 2835 if (caught_exception) { |
| 2831 return; | 2836 return; |
| 2832 } | 2837 } |
| 2833 | 2838 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2850 // No more to do if not debugging. | 2855 // No more to do if not debugging. |
| 2851 if (!IsDebuggerActive()) return; | 2856 if (!IsDebuggerActive()) return; |
| 2852 | 2857 |
| 2853 // No compile events while compiling natives. | 2858 // No compile events while compiling natives. |
| 2854 if (compiling_natives()) return; | 2859 if (compiling_natives()) return; |
| 2855 | 2860 |
| 2856 // Store whether in debugger before entering debugger. | 2861 // Store whether in debugger before entering debugger. |
| 2857 bool in_debugger = debug->InDebugger(); | 2862 bool in_debugger = debug->InDebugger(); |
| 2858 | 2863 |
| 2859 // Enter the debugger. | 2864 // Enter the debugger. |
| 2860 EnterDebugger debugger; | 2865 EnterDebugger debugger(isolate_); |
| 2861 if (debugger.FailedToEnter()) return; | 2866 if (debugger.FailedToEnter()) return; |
| 2862 | 2867 |
| 2863 // If debugging there might be script break points registered for this | 2868 // If debugging there might be script break points registered for this |
| 2864 // script. Make sure that these break points are set. | 2869 // script. Make sure that these break points are set. |
| 2865 | 2870 |
| 2866 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). | 2871 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). |
| 2867 Handle<String> update_script_break_points_string = | 2872 Handle<String> update_script_break_points_string = |
| 2868 isolate_->factory()->InternalizeOneByteString( | 2873 isolate_->factory()->InternalizeOneByteString( |
| 2869 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); | 2874 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); |
| 2870 Handle<Object> update_script_break_points = | 2875 Handle<Object> update_script_break_points = |
| 2871 Handle<Object>( | 2876 Handle<Object>( |
| 2872 debug->debug_context()->global_object()->GetPropertyNoExceptionThrown( | 2877 debug->debug_context()->global_object()->GetPropertyNoExceptionThrown( |
| 2873 *update_script_break_points_string), | 2878 *update_script_break_points_string), |
| 2874 isolate_); | 2879 isolate_); |
| 2875 if (!update_script_break_points->IsJSFunction()) { | 2880 if (!update_script_break_points->IsJSFunction()) { |
| 2876 return; | 2881 return; |
| 2877 } | 2882 } |
| 2878 ASSERT(update_script_break_points->IsJSFunction()); | 2883 ASSERT(update_script_break_points->IsJSFunction()); |
| 2879 | 2884 |
| 2880 // Wrap the script object in a proper JS object before passing it | 2885 // Wrap the script object in a proper JS object before passing it |
| 2881 // to JavaScript. | 2886 // to JavaScript. |
| 2882 Handle<JSValue> wrapper = GetScriptWrapper(script); | 2887 Handle<JSValue> wrapper = GetScriptWrapper(script); |
| 2883 | 2888 |
| 2884 // Call UpdateScriptBreakPoints expect no exceptions. | 2889 // Call UpdateScriptBreakPoints expect no exceptions. |
| 2885 bool caught_exception; | 2890 bool caught_exception; |
| 2886 Handle<Object> argv[] = { wrapper }; | 2891 Handle<Object> argv[] = { wrapper }; |
| 2887 Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points), | 2892 Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points), |
| 2888 Isolate::Current()->js_builtins_object(), | 2893 isolate_->js_builtins_object(), |
| 2889 ARRAY_SIZE(argv), | 2894 ARRAY_SIZE(argv), |
| 2890 argv, | 2895 argv, |
| 2891 &caught_exception); | 2896 &caught_exception); |
| 2892 if (caught_exception) { | 2897 if (caught_exception) { |
| 2893 return; | 2898 return; |
| 2894 } | 2899 } |
| 2895 // Bail out based on state or if there is no listener for this event | 2900 // Bail out based on state or if there is no listener for this event |
| 2896 if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return; | 2901 if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return; |
| 2897 if (!Debugger::EventActive(v8::AfterCompile)) return; | 2902 if (!Debugger::EventActive(v8::AfterCompile)) return; |
| 2898 | 2903 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2913 | 2918 |
| 2914 void Debugger::OnScriptCollected(int id) { | 2919 void Debugger::OnScriptCollected(int id) { |
| 2915 HandleScope scope(isolate_); | 2920 HandleScope scope(isolate_); |
| 2916 | 2921 |
| 2917 // No more to do if not debugging. | 2922 // No more to do if not debugging. |
| 2918 if (isolate_->debug()->InDebugger()) return; | 2923 if (isolate_->debug()->InDebugger()) return; |
| 2919 if (!IsDebuggerActive()) return; | 2924 if (!IsDebuggerActive()) return; |
| 2920 if (!Debugger::EventActive(v8::ScriptCollected)) return; | 2925 if (!Debugger::EventActive(v8::ScriptCollected)) return; |
| 2921 | 2926 |
| 2922 // Enter the debugger. | 2927 // Enter the debugger. |
| 2923 EnterDebugger debugger; | 2928 EnterDebugger debugger(isolate_); |
| 2924 if (debugger.FailedToEnter()) return; | 2929 if (debugger.FailedToEnter()) return; |
| 2925 | 2930 |
| 2926 // Create the script collected state object. | 2931 // Create the script collected state object. |
| 2927 bool caught_exception = false; | 2932 bool caught_exception = false; |
| 2928 Handle<Object> event_data = MakeScriptCollectedEvent(id, | 2933 Handle<Object> event_data = MakeScriptCollectedEvent(id, |
| 2929 &caught_exception); | 2934 &caught_exception); |
| 2930 // Bail out and don't call debugger if exception. | 2935 // Bail out and don't call debugger if exception. |
| 2931 if (caught_exception) { | 2936 if (caught_exception) { |
| 2932 return; | 2937 return; |
| 2933 } | 2938 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3030 isolate_->global_object(), | 3035 isolate_->global_object(), |
| 3031 ARRAY_SIZE(argv), | 3036 ARRAY_SIZE(argv), |
| 3032 argv, | 3037 argv, |
| 3033 &caught_exception); | 3038 &caught_exception); |
| 3034 // Silently ignore exceptions from debug event listeners. | 3039 // Silently ignore exceptions from debug event listeners. |
| 3035 } | 3040 } |
| 3036 | 3041 |
| 3037 | 3042 |
| 3038 Handle<Context> Debugger::GetDebugContext() { | 3043 Handle<Context> Debugger::GetDebugContext() { |
| 3039 never_unload_debugger_ = true; | 3044 never_unload_debugger_ = true; |
| 3040 EnterDebugger debugger; | 3045 EnterDebugger debugger(isolate_); |
| 3041 return isolate_->debug()->debug_context(); | 3046 return isolate_->debug()->debug_context(); |
| 3042 } | 3047 } |
| 3043 | 3048 |
| 3044 | 3049 |
| 3045 void Debugger::UnloadDebugger() { | 3050 void Debugger::UnloadDebugger() { |
| 3046 Debug* debug = isolate_->debug(); | 3051 Debug* debug = isolate_->debug(); |
| 3047 | 3052 |
| 3048 // Make sure that there are no breakpoints left. | 3053 // Make sure that there are no breakpoints left. |
| 3049 debug->ClearAllBreakPoints(); | 3054 debug->ClearAllBreakPoints(); |
| 3050 | 3055 |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3383 } | 3388 } |
| 3384 | 3389 |
| 3385 | 3390 |
| 3386 Handle<Object> Debugger::Call(Handle<JSFunction> fun, | 3391 Handle<Object> Debugger::Call(Handle<JSFunction> fun, |
| 3387 Handle<Object> data, | 3392 Handle<Object> data, |
| 3388 bool* pending_exception) { | 3393 bool* pending_exception) { |
| 3389 // When calling functions in the debugger prevent it from beeing unloaded. | 3394 // When calling functions in the debugger prevent it from beeing unloaded. |
| 3390 Debugger::never_unload_debugger_ = true; | 3395 Debugger::never_unload_debugger_ = true; |
| 3391 | 3396 |
| 3392 // Enter the debugger. | 3397 // Enter the debugger. |
| 3393 EnterDebugger debugger; | 3398 EnterDebugger debugger(isolate_); |
| 3394 if (debugger.FailedToEnter()) { | 3399 if (debugger.FailedToEnter()) { |
| 3395 return isolate_->factory()->undefined_value(); | 3400 return isolate_->factory()->undefined_value(); |
| 3396 } | 3401 } |
| 3397 | 3402 |
| 3398 // Create the execution state. | 3403 // Create the execution state. |
| 3399 bool caught_exception = false; | 3404 bool caught_exception = false; |
| 3400 Handle<Object> exec_state = MakeExecutionState(&caught_exception); | 3405 Handle<Object> exec_state = MakeExecutionState(&caught_exception); |
| 3401 if (caught_exception) { | 3406 if (caught_exception) { |
| 3402 return isolate_->factory()->undefined_value(); | 3407 return isolate_->factory()->undefined_value(); |
| 3403 } | 3408 } |
| 3404 | 3409 |
| 3405 Handle<Object> argv[] = { exec_state, data }; | 3410 Handle<Object> argv[] = { exec_state, data }; |
| 3406 Handle<Object> result = Execution::Call( | 3411 Handle<Object> result = Execution::Call( |
| 3412 isolate_, |
| 3407 fun, | 3413 fun, |
| 3408 Handle<Object>(isolate_->debug()->debug_context_->global_proxy(), | 3414 Handle<Object>(isolate_->debug()->debug_context_->global_proxy(), |
| 3409 isolate_), | 3415 isolate_), |
| 3410 ARRAY_SIZE(argv), | 3416 ARRAY_SIZE(argv), |
| 3411 argv, | 3417 argv, |
| 3412 pending_exception); | 3418 pending_exception); |
| 3413 return result; | 3419 return result; |
| 3414 } | 3420 } |
| 3415 | 3421 |
| 3416 | 3422 |
| 3417 static void StubMessageHandler2(const v8::Debug::Message& message) { | 3423 static void StubMessageHandler2(const v8::Debug::Message& message) { |
| 3418 // Simply ignore message. | 3424 // Simply ignore message. |
| 3419 } | 3425 } |
| 3420 | 3426 |
| 3421 | 3427 |
| 3422 bool Debugger::StartAgent(const char* name, int port, | 3428 bool Debugger::StartAgent(const char* name, int port, |
| 3423 bool wait_for_connection) { | 3429 bool wait_for_connection) { |
| 3424 ASSERT(Isolate::Current() == isolate_); | |
| 3425 if (wait_for_connection) { | 3430 if (wait_for_connection) { |
| 3426 // Suspend V8 if it is already running or set V8 to suspend whenever | 3431 // Suspend V8 if it is already running or set V8 to suspend whenever |
| 3427 // it starts. | 3432 // it starts. |
| 3428 // Provide stub message handler; V8 auto-continues each suspend | 3433 // Provide stub message handler; V8 auto-continues each suspend |
| 3429 // when there is no message handler; we doesn't need it. | 3434 // when there is no message handler; we doesn't need it. |
| 3430 // Once become suspended, V8 will stay so indefinitely long, until remote | 3435 // Once become suspended, V8 will stay so indefinitely long, until remote |
| 3431 // debugger connects and issues "continue" command. | 3436 // debugger connects and issues "continue" command. |
| 3432 Debugger::message_handler_ = StubMessageHandler2; | 3437 Debugger::message_handler_ = StubMessageHandler2; |
| 3433 v8::Debug::DebugBreak(); | 3438 v8::Debug::DebugBreak(); |
| 3434 } | 3439 } |
| 3435 | 3440 |
| 3436 if (Socket::SetUp()) { | 3441 if (agent_ == NULL) { |
| 3437 if (agent_ == NULL) { | 3442 agent_ = new DebuggerAgent(isolate_, name, port); |
| 3438 agent_ = new DebuggerAgent(name, port); | 3443 agent_->Start(); |
| 3439 agent_->Start(); | |
| 3440 } | |
| 3441 return true; | |
| 3442 } | 3444 } |
| 3443 | 3445 return true; |
| 3444 return false; | |
| 3445 } | 3446 } |
| 3446 | 3447 |
| 3447 | 3448 |
| 3448 void Debugger::StopAgent() { | 3449 void Debugger::StopAgent() { |
| 3449 ASSERT(Isolate::Current() == isolate_); | |
| 3450 if (agent_ != NULL) { | 3450 if (agent_ != NULL) { |
| 3451 agent_->Shutdown(); | 3451 agent_->Shutdown(); |
| 3452 agent_->Join(); | 3452 agent_->Join(); |
| 3453 delete agent_; | 3453 delete agent_; |
| 3454 agent_ = NULL; | 3454 agent_ = NULL; |
| 3455 } | 3455 } |
| 3456 } | 3456 } |
| 3457 | 3457 |
| 3458 | 3458 |
| 3459 void Debugger::WaitForAgent() { | 3459 void Debugger::WaitForAgent() { |
| 3460 ASSERT(Isolate::Current() == isolate_); | |
| 3461 if (agent_ != NULL) | 3460 if (agent_ != NULL) |
| 3462 agent_->WaitUntilListening(); | 3461 agent_->WaitUntilListening(); |
| 3463 } | 3462 } |
| 3464 | 3463 |
| 3465 | 3464 |
| 3466 void Debugger::CallMessageDispatchHandler() { | 3465 void Debugger::CallMessageDispatchHandler() { |
| 3467 v8::Debug::DebugMessageDispatchHandler handler; | 3466 v8::Debug::DebugMessageDispatchHandler handler; |
| 3468 { | 3467 { |
| 3469 LockGuard<Mutex> lock_guard(&dispatch_handler_access_); | 3468 LockGuard<Mutex> lock_guard(&dispatch_handler_access_); |
| 3470 handler = Debugger::debug_message_dispatch_handler_; | 3469 handler = Debugger::debug_message_dispatch_handler_; |
| 3471 } | 3470 } |
| 3472 if (handler != NULL) { | 3471 if (handler != NULL) { |
| 3473 handler(); | 3472 handler(); |
| 3474 } | 3473 } |
| 3475 } | 3474 } |
| 3476 | 3475 |
| 3477 | 3476 |
| 3478 EnterDebugger::EnterDebugger() | 3477 EnterDebugger::EnterDebugger(Isolate* isolate) |
| 3479 : isolate_(Isolate::Current()), | 3478 : isolate_(isolate), |
| 3480 prev_(isolate_->debug()->debugger_entry()), | 3479 prev_(isolate_->debug()->debugger_entry()), |
| 3481 it_(isolate_), | 3480 it_(isolate_), |
| 3482 has_js_frames_(!it_.done()), | 3481 has_js_frames_(!it_.done()), |
| 3483 save_(isolate_) { | 3482 save_(isolate_) { |
| 3484 Debug* debug = isolate_->debug(); | 3483 Debug* debug = isolate_->debug(); |
| 3485 ASSERT(prev_ != NULL || !debug->is_interrupt_pending(PREEMPT)); | 3484 ASSERT(prev_ != NULL || !debug->is_interrupt_pending(PREEMPT)); |
| 3486 ASSERT(prev_ != NULL || !debug->is_interrupt_pending(DEBUGBREAK)); | 3485 ASSERT(prev_ != NULL || !debug->is_interrupt_pending(DEBUGBREAK)); |
| 3487 | 3486 |
| 3488 // Link recursive debugger entry. | 3487 // Link recursive debugger entry. |
| 3489 debug->set_debugger_entry(this); | 3488 debug->set_debugger_entry(this); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3504 load_failed_ = !debug->Load(); | 3503 load_failed_ = !debug->Load(); |
| 3505 if (!load_failed_) { | 3504 if (!load_failed_) { |
| 3506 // NOTE the member variable save which saves the previous context before | 3505 // NOTE the member variable save which saves the previous context before |
| 3507 // this change. | 3506 // this change. |
| 3508 isolate_->set_context(*debug->debug_context()); | 3507 isolate_->set_context(*debug->debug_context()); |
| 3509 } | 3508 } |
| 3510 } | 3509 } |
| 3511 | 3510 |
| 3512 | 3511 |
| 3513 EnterDebugger::~EnterDebugger() { | 3512 EnterDebugger::~EnterDebugger() { |
| 3514 ASSERT(Isolate::Current() == isolate_); | |
| 3515 Debug* debug = isolate_->debug(); | 3513 Debug* debug = isolate_->debug(); |
| 3516 | 3514 |
| 3517 // Restore to the previous break state. | 3515 // Restore to the previous break state. |
| 3518 debug->SetBreak(break_frame_id_, break_id_); | 3516 debug->SetBreak(break_frame_id_, break_id_); |
| 3519 | 3517 |
| 3520 // Check for leaving the debugger. | 3518 // Check for leaving the debugger. |
| 3521 if (!load_failed_ && prev_ == NULL) { | 3519 if (!load_failed_ && prev_ == NULL) { |
| 3522 // Clear mirror cache when leaving the debugger. Skip this if there is a | 3520 // Clear mirror cache when leaving the debugger. Skip this if there is a |
| 3523 // pending exception as clearing the mirror cache calls back into | 3521 // pending exception as clearing the mirror cache calls back into |
| 3524 // JavaScript. This can happen if the v8::Debug::Call is used in which | 3522 // JavaScript. This can happen if the v8::Debug::Call is used in which |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3649 return v8::Handle<v8::String>(); | 3647 return v8::Handle<v8::String>(); |
| 3650 } | 3648 } |
| 3651 return scope.Close(v8::Utils::ToLocal(Handle<String>::cast(json))); | 3649 return scope.Close(v8::Utils::ToLocal(Handle<String>::cast(json))); |
| 3652 } else { | 3650 } else { |
| 3653 return v8::Utils::ToLocal(response_json_); | 3651 return v8::Utils::ToLocal(response_json_); |
| 3654 } | 3652 } |
| 3655 } | 3653 } |
| 3656 | 3654 |
| 3657 | 3655 |
| 3658 v8::Handle<v8::Context> MessageImpl::GetEventContext() const { | 3656 v8::Handle<v8::Context> MessageImpl::GetEventContext() const { |
| 3659 Isolate* isolate = Isolate::Current(); | 3657 Isolate* isolate = event_data_->GetIsolate(); |
| 3660 v8::Handle<v8::Context> context = GetDebugEventContext(isolate); | 3658 v8::Handle<v8::Context> context = GetDebugEventContext(isolate); |
| 3661 // Isolate::context() may be NULL when "script collected" event occures. | 3659 // Isolate::context() may be NULL when "script collected" event occures. |
| 3662 ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected); | 3660 ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected); |
| 3663 return context; | 3661 return context; |
| 3664 } | 3662 } |
| 3665 | 3663 |
| 3666 | 3664 |
| 3667 v8::Debug::ClientData* MessageImpl::GetClientData() const { | 3665 v8::Debug::ClientData* MessageImpl::GetClientData() const { |
| 3668 return client_data_; | 3666 return client_data_; |
| 3669 } | 3667 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3690 return v8::Utils::ToLocal(exec_state_); | 3688 return v8::Utils::ToLocal(exec_state_); |
| 3691 } | 3689 } |
| 3692 | 3690 |
| 3693 | 3691 |
| 3694 v8::Handle<v8::Object> EventDetailsImpl::GetEventData() const { | 3692 v8::Handle<v8::Object> EventDetailsImpl::GetEventData() const { |
| 3695 return v8::Utils::ToLocal(event_data_); | 3693 return v8::Utils::ToLocal(event_data_); |
| 3696 } | 3694 } |
| 3697 | 3695 |
| 3698 | 3696 |
| 3699 v8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const { | 3697 v8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const { |
| 3700 return GetDebugEventContext(Isolate::Current()); | 3698 return GetDebugEventContext(exec_state_->GetIsolate()); |
| 3701 } | 3699 } |
| 3702 | 3700 |
| 3703 | 3701 |
| 3704 v8::Handle<v8::Value> EventDetailsImpl::GetCallbackData() const { | 3702 v8::Handle<v8::Value> EventDetailsImpl::GetCallbackData() const { |
| 3705 return v8::Utils::ToLocal(callback_data_); | 3703 return v8::Utils::ToLocal(callback_data_); |
| 3706 } | 3704 } |
| 3707 | 3705 |
| 3708 | 3706 |
| 3709 v8::Debug::ClientData* EventDetailsImpl::GetClientData() const { | 3707 v8::Debug::ClientData* EventDetailsImpl::GetClientData() const { |
| 3710 return client_data_; | 3708 return client_data_; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3846 { | 3844 { |
| 3847 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); | 3845 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); |
| 3848 isolate_->debugger()->CallMessageDispatchHandler(); | 3846 isolate_->debugger()->CallMessageDispatchHandler(); |
| 3849 } | 3847 } |
| 3850 } | 3848 } |
| 3851 } | 3849 } |
| 3852 | 3850 |
| 3853 #endif // ENABLE_DEBUGGER_SUPPORT | 3851 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3854 | 3852 |
| 3855 } } // namespace v8::internal | 3853 } } // namespace v8::internal |
| OLD | NEW |