Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 789 Handle<Script> script(Script::cast(function->shared()->script())); | 789 Handle<Script> script(Script::cast(function->shared()->script())); |
| 790 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 790 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
| 791 return true; | 791 return true; |
| 792 } | 792 } |
| 793 | 793 |
| 794 | 794 |
| 795 bool Debug::Load() { | 795 bool Debug::Load() { |
| 796 // Return if debugger is already loaded. | 796 // Return if debugger is already loaded. |
| 797 if (IsLoaded()) return true; | 797 if (IsLoaded()) return true; |
| 798 | 798 |
| 799 ASSERT(Isolate::Current() == isolate_); | |
|
Vitaly Repeshko
2011/06/10 08:18:50
Some of these asserts are useful as the isolate is
mnaganov (inactive)
2011/06/10 09:31:32
http://code.google.com/p/v8/issues/detail?id=1449
| |
| 800 Debugger* debugger = isolate_->debugger(); | 799 Debugger* debugger = isolate_->debugger(); |
| 801 | 800 |
| 802 // Bail out if we're already in the process of compiling the native | 801 // Bail out if we're already in the process of compiling the native |
| 803 // JavaScript source code for the debugger. | 802 // JavaScript source code for the debugger. |
| 804 if (debugger->compiling_natives() || | 803 if (debugger->compiling_natives() || |
| 805 debugger->is_loading_debugger()) | 804 debugger->is_loading_debugger()) |
| 806 return false; | 805 return false; |
| 807 debugger->set_loading_debugger(true); | 806 debugger->set_loading_debugger(true); |
| 808 | 807 |
| 809 // Disable breakpoints and interrupts while compiling and running the | 808 // Disable breakpoints and interrupts while compiling and running the |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1041 } | 1040 } |
| 1042 // Return break points hit as a JSArray. | 1041 // Return break points hit as a JSArray. |
| 1043 Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit); | 1042 Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit); |
| 1044 result->set_length(Smi::FromInt(break_points_hit_count)); | 1043 result->set_length(Smi::FromInt(break_points_hit_count)); |
| 1045 return result; | 1044 return result; |
| 1046 } | 1045 } |
| 1047 | 1046 |
| 1048 | 1047 |
| 1049 // Check whether a single break point object is triggered. | 1048 // Check whether a single break point object is triggered. |
| 1050 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) { | 1049 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) { |
| 1051 ASSERT(Isolate::Current() == isolate_); | |
| 1052 Factory* factory = isolate_->factory(); | 1050 Factory* factory = isolate_->factory(); |
| 1053 HandleScope scope(isolate_); | 1051 HandleScope scope(isolate_); |
| 1054 | 1052 |
| 1055 // Ignore check if break point object is not a JSObject. | 1053 // Ignore check if break point object is not a JSObject. |
| 1056 if (!break_point_object->IsJSObject()) return true; | 1054 if (!break_point_object->IsJSObject()) return true; |
| 1057 | 1055 |
| 1058 // Get the function IsBreakPointTriggered (defined in debug-debugger.js). | 1056 // Get the function IsBreakPointTriggered (defined in debug-debugger.js). |
| 1059 Handle<String> is_break_point_triggered_symbol = | 1057 Handle<String> is_break_point_triggered_symbol = |
| 1060 factory->LookupAsciiSymbol("IsBreakPointTriggered"); | 1058 factory->LookupAsciiSymbol("IsBreakPointTriggered"); |
| 1061 Handle<JSFunction> check_break_point = | 1059 Handle<JSFunction> check_break_point = |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1227 bool Debug::IsBreakOnException(ExceptionBreakType type) { | 1225 bool Debug::IsBreakOnException(ExceptionBreakType type) { |
| 1228 if (type == BreakUncaughtException) { | 1226 if (type == BreakUncaughtException) { |
| 1229 return break_on_uncaught_exception_; | 1227 return break_on_uncaught_exception_; |
| 1230 } else { | 1228 } else { |
| 1231 return break_on_exception_; | 1229 return break_on_exception_; |
| 1232 } | 1230 } |
| 1233 } | 1231 } |
| 1234 | 1232 |
| 1235 | 1233 |
| 1236 void Debug::PrepareStep(StepAction step_action, int step_count) { | 1234 void Debug::PrepareStep(StepAction step_action, int step_count) { |
| 1237 ASSERT(Isolate::Current() == isolate_); | |
| 1238 HandleScope scope(isolate_); | 1235 HandleScope scope(isolate_); |
| 1239 ASSERT(Debug::InDebugger()); | 1236 ASSERT(Debug::InDebugger()); |
| 1240 | 1237 |
| 1241 // Remember this step action and count. | 1238 // Remember this step action and count. |
| 1242 thread_local_.last_step_action_ = step_action; | 1239 thread_local_.last_step_action_ = step_action; |
| 1243 if (step_action == StepOut) { | 1240 if (step_action == StepOut) { |
| 1244 // For step out target frame will be found on the stack so there is no need | 1241 // For step out target frame will be found on the stack so there is no need |
| 1245 // to set step counter for it. It's expected to always be 0 for StepOut. | 1242 // to set step counter for it. It's expected to always be 0 for StepOut. |
| 1246 thread_local_.step_count_ = 0; | 1243 thread_local_.step_count_ = 0; |
| 1247 } else { | 1244 } else { |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1732 } | 1729 } |
| 1733 // Move to next in list. | 1730 // Move to next in list. |
| 1734 prev = current; | 1731 prev = current; |
| 1735 current = current->next(); | 1732 current = current->next(); |
| 1736 } | 1733 } |
| 1737 UNREACHABLE(); | 1734 UNREACHABLE(); |
| 1738 } | 1735 } |
| 1739 | 1736 |
| 1740 | 1737 |
| 1741 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { | 1738 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { |
| 1742 ASSERT(Isolate::Current() == isolate_); | |
| 1743 HandleScope scope(isolate_); | 1739 HandleScope scope(isolate_); |
| 1744 | 1740 |
| 1745 // Get the executing function in which the debug break occurred. | 1741 // Get the executing function in which the debug break occurred. |
| 1746 Handle<SharedFunctionInfo> shared = | 1742 Handle<SharedFunctionInfo> shared = |
| 1747 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 1743 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); |
| 1748 if (!EnsureDebugInfo(shared)) { | 1744 if (!EnsureDebugInfo(shared)) { |
| 1749 // Return if we failed to retrieve the debug info. | 1745 // Return if we failed to retrieve the debug info. |
| 1750 return; | 1746 return; |
| 1751 } | 1747 } |
| 1752 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1748 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1865 restarter_frame_function_pointer; | 1861 restarter_frame_function_pointer; |
| 1866 } | 1862 } |
| 1867 | 1863 |
| 1868 | 1864 |
| 1869 bool Debug::IsDebugGlobal(GlobalObject* global) { | 1865 bool Debug::IsDebugGlobal(GlobalObject* global) { |
| 1870 return IsLoaded() && global == debug_context()->global(); | 1866 return IsLoaded() && global == debug_context()->global(); |
| 1871 } | 1867 } |
| 1872 | 1868 |
| 1873 | 1869 |
| 1874 void Debug::ClearMirrorCache() { | 1870 void Debug::ClearMirrorCache() { |
| 1875 ASSERT(Isolate::Current() == isolate_); | |
| 1876 PostponeInterruptsScope postpone(isolate_); | 1871 PostponeInterruptsScope postpone(isolate_); |
| 1877 HandleScope scope(isolate_); | 1872 HandleScope scope(isolate_); |
| 1878 ASSERT(isolate_->context() == *Debug::debug_context()); | 1873 ASSERT(isolate_->context() == *Debug::debug_context()); |
| 1879 | 1874 |
| 1880 // Clear the mirror cache. | 1875 // Clear the mirror cache. |
| 1881 Handle<String> function_name = | 1876 Handle<String> function_name = |
| 1882 isolate_->factory()->LookupSymbol(CStrVector("ClearMirrorCache")); | 1877 isolate_->factory()->LookupSymbol(CStrVector("ClearMirrorCache")); |
| 1883 Handle<Object> fun(Isolate::Current()->global()->GetPropertyNoExceptionThrown( | 1878 Handle<Object> fun(Isolate::Current()->global()->GetPropertyNoExceptionThrown( |
| 1884 *function_name)); | 1879 *function_name)); |
| 1885 ASSERT(fun->IsJSFunction()); | 1880 ASSERT(fun->IsJSFunction()); |
| 1886 bool caught_exception; | 1881 bool caught_exception; |
| 1887 Handle<Object> js_object = Execution::TryCall( | 1882 Handle<Object> js_object = Execution::TryCall( |
| 1888 Handle<JSFunction>::cast(fun), | 1883 Handle<JSFunction>::cast(fun), |
| 1889 Handle<JSObject>(Debug::debug_context()->global()), | 1884 Handle<JSObject>(Debug::debug_context()->global()), |
| 1890 0, NULL, &caught_exception); | 1885 0, NULL, &caught_exception); |
| 1891 } | 1886 } |
| 1892 | 1887 |
| 1893 | 1888 |
| 1894 void Debug::CreateScriptCache() { | 1889 void Debug::CreateScriptCache() { |
| 1895 ASSERT(Isolate::Current() == isolate_); | |
| 1896 Heap* heap = isolate_->heap(); | 1890 Heap* heap = isolate_->heap(); |
| 1897 HandleScope scope(isolate_); | 1891 HandleScope scope(isolate_); |
| 1898 | 1892 |
| 1899 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets | 1893 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets |
| 1900 // rid of all the cached script wrappers and the second gets rid of the | 1894 // rid of all the cached script wrappers and the second gets rid of the |
| 1901 // scripts which are no longer referenced. | 1895 // scripts which are no longer referenced. |
| 1902 heap->CollectAllGarbage(false); | 1896 heap->CollectAllGarbage(false); |
| 1903 heap->CollectAllGarbage(false); | 1897 heap->CollectAllGarbage(false); |
| 1904 | 1898 |
| 1905 ASSERT(script_cache_ == NULL); | 1899 ASSERT(script_cache_ == NULL); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1927 | 1921 |
| 1928 | 1922 |
| 1929 void Debug::AddScriptToScriptCache(Handle<Script> script) { | 1923 void Debug::AddScriptToScriptCache(Handle<Script> script) { |
| 1930 if (script_cache_ != NULL) { | 1924 if (script_cache_ != NULL) { |
| 1931 script_cache_->Add(script); | 1925 script_cache_->Add(script); |
| 1932 } | 1926 } |
| 1933 } | 1927 } |
| 1934 | 1928 |
| 1935 | 1929 |
| 1936 Handle<FixedArray> Debug::GetLoadedScripts() { | 1930 Handle<FixedArray> Debug::GetLoadedScripts() { |
| 1937 ASSERT(Isolate::Current() == isolate_); | |
| 1938 // Create and fill the script cache when the loaded scripts is requested for | 1931 // Create and fill the script cache when the loaded scripts is requested for |
| 1939 // the first time. | 1932 // the first time. |
| 1940 if (script_cache_ == NULL) { | 1933 if (script_cache_ == NULL) { |
| 1941 CreateScriptCache(); | 1934 CreateScriptCache(); |
| 1942 } | 1935 } |
| 1943 | 1936 |
| 1944 // If the script cache is not active just return an empty array. | 1937 // If the script cache is not active just return an empty array. |
| 1945 ASSERT(script_cache_ != NULL); | 1938 ASSERT(script_cache_ != NULL); |
| 1946 if (script_cache_ == NULL) { | 1939 if (script_cache_ == NULL) { |
| 1947 isolate_->factory()->NewFixedArray(0); | 1940 isolate_->factory()->NewFixedArray(0); |
| 1948 } | 1941 } |
| 1949 | 1942 |
| 1950 // Perform GC to get unreferenced scripts evicted from the cache before | 1943 // Perform GC to get unreferenced scripts evicted from the cache before |
| 1951 // returning the content. | 1944 // returning the content. |
| 1952 isolate_->heap()->CollectAllGarbage(false); | 1945 isolate_->heap()->CollectAllGarbage(false); |
| 1953 | 1946 |
| 1954 // Get the scripts from the cache. | 1947 // Get the scripts from the cache. |
| 1955 return script_cache_->GetScripts(); | 1948 return script_cache_->GetScripts(); |
| 1956 } | 1949 } |
| 1957 | 1950 |
| 1958 | 1951 |
| 1959 void Debug::AfterGarbageCollection() { | 1952 void Debug::AfterGarbageCollection() { |
| 1960 // Generate events for collected scripts. | 1953 // Generate events for collected scripts. |
| 1961 if (script_cache_ != NULL) { | 1954 if (script_cache_ != NULL) { |
| 1962 script_cache_->ProcessCollectedScripts(); | 1955 script_cache_->ProcessCollectedScripts(); |
| 1963 } | 1956 } |
| 1964 } | 1957 } |
| 1965 | 1958 |
| 1966 | 1959 |
| 1967 Debugger::Debugger() | 1960 Debugger::Debugger(Isolate* isolate) |
| 1968 : debugger_access_(OS::CreateMutex()), | 1961 : debugger_access_(OS::CreateMutex()), |
| 1969 event_listener_(Handle<Object>()), | 1962 event_listener_(Handle<Object>()), |
| 1970 event_listener_data_(Handle<Object>()), | 1963 event_listener_data_(Handle<Object>()), |
| 1971 compiling_natives_(false), | 1964 compiling_natives_(false), |
| 1972 is_loading_debugger_(false), | 1965 is_loading_debugger_(false), |
| 1973 never_unload_debugger_(false), | 1966 never_unload_debugger_(false), |
| 1974 message_handler_(NULL), | 1967 message_handler_(NULL), |
| 1975 debugger_unload_pending_(false), | 1968 debugger_unload_pending_(false), |
| 1976 host_dispatch_handler_(NULL), | 1969 host_dispatch_handler_(NULL), |
| 1977 dispatch_handler_access_(OS::CreateMutex()), | 1970 dispatch_handler_access_(OS::CreateMutex()), |
| 1978 debug_message_dispatch_handler_(NULL), | 1971 debug_message_dispatch_handler_(NULL), |
| 1979 message_dispatch_helper_thread_(NULL), | 1972 message_dispatch_helper_thread_(NULL), |
| 1980 host_dispatch_micros_(100 * 1000), | 1973 host_dispatch_micros_(100 * 1000), |
| 1981 agent_(NULL), | 1974 agent_(NULL), |
| 1982 command_queue_(kQueueInitialSize), | 1975 command_queue_(isolate->logger(), kQueueInitialSize), |
| 1983 command_received_(OS::CreateSemaphore(0)), | 1976 command_received_(OS::CreateSemaphore(0)), |
| 1984 event_command_queue_(kQueueInitialSize) { | 1977 event_command_queue_(isolate->logger(), kQueueInitialSize), |
| 1978 isolate_(isolate) { | |
| 1985 } | 1979 } |
| 1986 | 1980 |
| 1987 | 1981 |
| 1988 Debugger::~Debugger() { | 1982 Debugger::~Debugger() { |
| 1989 delete debugger_access_; | 1983 delete debugger_access_; |
| 1990 debugger_access_ = 0; | 1984 debugger_access_ = 0; |
| 1991 delete dispatch_handler_access_; | 1985 delete dispatch_handler_access_; |
| 1992 dispatch_handler_access_ = 0; | 1986 dispatch_handler_access_ = 0; |
| 1993 delete command_received_; | 1987 delete command_received_; |
| 1994 command_received_ = 0; | 1988 command_received_ = 0; |
| 1995 } | 1989 } |
| 1996 | 1990 |
| 1997 | 1991 |
| 1998 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, | 1992 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, |
| 1999 int argc, Object*** argv, | 1993 int argc, Object*** argv, |
| 2000 bool* caught_exception) { | 1994 bool* caught_exception) { |
| 2001 ASSERT(Isolate::Current() == isolate_); | |
| 2002 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); | 1995 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); |
| 2003 | 1996 |
| 2004 // Create the execution state object. | 1997 // Create the execution state object. |
| 2005 Handle<String> constructor_str = | 1998 Handle<String> constructor_str = |
| 2006 isolate_->factory()->LookupSymbol(constructor_name); | 1999 isolate_->factory()->LookupSymbol(constructor_name); |
| 2007 Handle<Object> constructor( | 2000 Handle<Object> constructor( |
| 2008 isolate_->global()->GetPropertyNoExceptionThrown(*constructor_str)); | 2001 isolate_->global()->GetPropertyNoExceptionThrown(*constructor_str)); |
| 2009 ASSERT(constructor->IsJSFunction()); | 2002 ASSERT(constructor->IsJSFunction()); |
| 2010 if (!constructor->IsJSFunction()) { | 2003 if (!constructor->IsJSFunction()) { |
| 2011 *caught_exception = true; | 2004 *caught_exception = true; |
| 2012 return isolate_->factory()->undefined_value(); | 2005 return isolate_->factory()->undefined_value(); |
| 2013 } | 2006 } |
| 2014 Handle<Object> js_object = Execution::TryCall( | 2007 Handle<Object> js_object = Execution::TryCall( |
| 2015 Handle<JSFunction>::cast(constructor), | 2008 Handle<JSFunction>::cast(constructor), |
| 2016 Handle<JSObject>(isolate_->debug()->debug_context()->global()), | 2009 Handle<JSObject>(isolate_->debug()->debug_context()->global()), |
| 2017 argc, argv, caught_exception); | 2010 argc, argv, caught_exception); |
| 2018 return js_object; | 2011 return js_object; |
| 2019 } | 2012 } |
| 2020 | 2013 |
| 2021 | 2014 |
| 2022 Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) { | 2015 Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) { |
| 2023 ASSERT(Isolate::Current() == isolate_); | |
| 2024 // Create the execution state object. | 2016 // Create the execution state object. |
| 2025 Handle<Object> break_id = isolate_->factory()->NewNumberFromInt( | 2017 Handle<Object> break_id = isolate_->factory()->NewNumberFromInt( |
| 2026 isolate_->debug()->break_id()); | 2018 isolate_->debug()->break_id()); |
| 2027 const int argc = 1; | 2019 const int argc = 1; |
| 2028 Object** argv[argc] = { break_id.location() }; | 2020 Object** argv[argc] = { break_id.location() }; |
| 2029 return MakeJSObject(CStrVector("MakeExecutionState"), | 2021 return MakeJSObject(CStrVector("MakeExecutionState"), |
| 2030 argc, argv, caught_exception); | 2022 argc, argv, caught_exception); |
| 2031 } | 2023 } |
| 2032 | 2024 |
| 2033 | 2025 |
| 2034 Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state, | 2026 Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state, |
| 2035 Handle<Object> break_points_hit, | 2027 Handle<Object> break_points_hit, |
| 2036 bool* caught_exception) { | 2028 bool* caught_exception) { |
| 2037 ASSERT(Isolate::Current() == isolate_); | |
| 2038 // Create the new break event object. | 2029 // Create the new break event object. |
| 2039 const int argc = 2; | 2030 const int argc = 2; |
| 2040 Object** argv[argc] = { exec_state.location(), | 2031 Object** argv[argc] = { exec_state.location(), |
| 2041 break_points_hit.location() }; | 2032 break_points_hit.location() }; |
| 2042 return MakeJSObject(CStrVector("MakeBreakEvent"), | 2033 return MakeJSObject(CStrVector("MakeBreakEvent"), |
| 2043 argc, | 2034 argc, |
| 2044 argv, | 2035 argv, |
| 2045 caught_exception); | 2036 caught_exception); |
| 2046 } | 2037 } |
| 2047 | 2038 |
| 2048 | 2039 |
| 2049 Handle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state, | 2040 Handle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state, |
| 2050 Handle<Object> exception, | 2041 Handle<Object> exception, |
| 2051 bool uncaught, | 2042 bool uncaught, |
| 2052 bool* caught_exception) { | 2043 bool* caught_exception) { |
| 2053 ASSERT(Isolate::Current() == isolate_); | |
| 2054 Factory* factory = isolate_->factory(); | 2044 Factory* factory = isolate_->factory(); |
| 2055 // Create the new exception event object. | 2045 // Create the new exception event object. |
| 2056 const int argc = 3; | 2046 const int argc = 3; |
| 2057 Object** argv[argc] = { exec_state.location(), | 2047 Object** argv[argc] = { exec_state.location(), |
| 2058 exception.location(), | 2048 exception.location(), |
| 2059 uncaught ? factory->true_value().location() : | 2049 uncaught ? factory->true_value().location() : |
| 2060 factory->false_value().location()}; | 2050 factory->false_value().location()}; |
| 2061 return MakeJSObject(CStrVector("MakeExceptionEvent"), | 2051 return MakeJSObject(CStrVector("MakeExceptionEvent"), |
| 2062 argc, argv, caught_exception); | 2052 argc, argv, caught_exception); |
| 2063 } | 2053 } |
| 2064 | 2054 |
| 2065 | 2055 |
| 2066 Handle<Object> Debugger::MakeNewFunctionEvent(Handle<Object> function, | 2056 Handle<Object> Debugger::MakeNewFunctionEvent(Handle<Object> function, |
| 2067 bool* caught_exception) { | 2057 bool* caught_exception) { |
| 2068 ASSERT(Isolate::Current() == isolate_); | |
| 2069 // Create the new function event object. | 2058 // Create the new function event object. |
| 2070 const int argc = 1; | 2059 const int argc = 1; |
| 2071 Object** argv[argc] = { function.location() }; | 2060 Object** argv[argc] = { function.location() }; |
| 2072 return MakeJSObject(CStrVector("MakeNewFunctionEvent"), | 2061 return MakeJSObject(CStrVector("MakeNewFunctionEvent"), |
| 2073 argc, argv, caught_exception); | 2062 argc, argv, caught_exception); |
| 2074 } | 2063 } |
| 2075 | 2064 |
| 2076 | 2065 |
| 2077 Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script, | 2066 Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script, |
| 2078 bool before, | 2067 bool before, |
| 2079 bool* caught_exception) { | 2068 bool* caught_exception) { |
| 2080 ASSERT(Isolate::Current() == isolate_); | |
| 2081 Factory* factory = isolate_->factory(); | 2069 Factory* factory = isolate_->factory(); |
| 2082 // Create the compile event object. | 2070 // Create the compile event object. |
| 2083 Handle<Object> exec_state = MakeExecutionState(caught_exception); | 2071 Handle<Object> exec_state = MakeExecutionState(caught_exception); |
| 2084 Handle<Object> script_wrapper = GetScriptWrapper(script); | 2072 Handle<Object> script_wrapper = GetScriptWrapper(script); |
| 2085 const int argc = 3; | 2073 const int argc = 3; |
| 2086 Object** argv[argc] = { exec_state.location(), | 2074 Object** argv[argc] = { exec_state.location(), |
| 2087 script_wrapper.location(), | 2075 script_wrapper.location(), |
| 2088 before ? factory->true_value().location() : | 2076 before ? factory->true_value().location() : |
| 2089 factory->false_value().location() }; | 2077 factory->false_value().location() }; |
| 2090 | 2078 |
| 2091 return MakeJSObject(CStrVector("MakeCompileEvent"), | 2079 return MakeJSObject(CStrVector("MakeCompileEvent"), |
| 2092 argc, | 2080 argc, |
| 2093 argv, | 2081 argv, |
| 2094 caught_exception); | 2082 caught_exception); |
| 2095 } | 2083 } |
| 2096 | 2084 |
| 2097 | 2085 |
| 2098 Handle<Object> Debugger::MakeScriptCollectedEvent(int id, | 2086 Handle<Object> Debugger::MakeScriptCollectedEvent(int id, |
| 2099 bool* caught_exception) { | 2087 bool* caught_exception) { |
| 2100 ASSERT(Isolate::Current() == isolate_); | |
| 2101 // Create the script collected event object. | 2088 // Create the script collected event object. |
| 2102 Handle<Object> exec_state = MakeExecutionState(caught_exception); | 2089 Handle<Object> exec_state = MakeExecutionState(caught_exception); |
| 2103 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id)); | 2090 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id)); |
| 2104 const int argc = 2; | 2091 const int argc = 2; |
| 2105 Object** argv[argc] = { exec_state.location(), id_object.location() }; | 2092 Object** argv[argc] = { exec_state.location(), id_object.location() }; |
| 2106 | 2093 |
| 2107 return MakeJSObject(CStrVector("MakeScriptCollectedEvent"), | 2094 return MakeJSObject(CStrVector("MakeScriptCollectedEvent"), |
| 2108 argc, | 2095 argc, |
| 2109 argv, | 2096 argv, |
| 2110 caught_exception); | 2097 caught_exception); |
| 2111 } | 2098 } |
| 2112 | 2099 |
| 2113 | 2100 |
| 2114 void Debugger::OnException(Handle<Object> exception, bool uncaught) { | 2101 void Debugger::OnException(Handle<Object> exception, bool uncaught) { |
| 2115 ASSERT(Isolate::Current() == isolate_); | |
| 2116 HandleScope scope(isolate_); | 2102 HandleScope scope(isolate_); |
| 2117 Debug* debug = isolate_->debug(); | 2103 Debug* debug = isolate_->debug(); |
| 2118 | 2104 |
| 2119 // Bail out based on state or if there is no listener for this event | 2105 // Bail out based on state or if there is no listener for this event |
| 2120 if (debug->InDebugger()) return; | 2106 if (debug->InDebugger()) return; |
| 2121 if (!Debugger::EventActive(v8::Exception)) return; | 2107 if (!Debugger::EventActive(v8::Exception)) return; |
| 2122 | 2108 |
| 2123 // Bail out if exception breaks are not active | 2109 // Bail out if exception breaks are not active |
| 2124 if (uncaught) { | 2110 if (uncaught) { |
| 2125 // Uncaught exceptions are reported by either flags. | 2111 // Uncaught exceptions are reported by either flags. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2150 } | 2136 } |
| 2151 | 2137 |
| 2152 // Process debug event. | 2138 // Process debug event. |
| 2153 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); | 2139 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); |
| 2154 // Return to continue execution from where the exception was thrown. | 2140 // Return to continue execution from where the exception was thrown. |
| 2155 } | 2141 } |
| 2156 | 2142 |
| 2157 | 2143 |
| 2158 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, | 2144 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, |
| 2159 bool auto_continue) { | 2145 bool auto_continue) { |
| 2160 ASSERT(Isolate::Current() == isolate_); | |
| 2161 HandleScope scope(isolate_); | 2146 HandleScope scope(isolate_); |
| 2162 | 2147 |
| 2163 // Debugger has already been entered by caller. | 2148 // Debugger has already been entered by caller. |
| 2164 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); | 2149 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); |
| 2165 | 2150 |
| 2166 // Bail out if there is no listener for this event | 2151 // Bail out if there is no listener for this event |
| 2167 if (!Debugger::EventActive(v8::Break)) return; | 2152 if (!Debugger::EventActive(v8::Break)) return; |
| 2168 | 2153 |
| 2169 // Debugger must be entered in advance. | 2154 // Debugger must be entered in advance. |
| 2170 ASSERT(Isolate::Current()->context() == *isolate_->debug()->debug_context()); | 2155 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); |
| 2171 | 2156 |
| 2172 // Create the event data object. | 2157 // Create the event data object. |
| 2173 bool caught_exception = false; | 2158 bool caught_exception = false; |
| 2174 Handle<Object> exec_state = MakeExecutionState(&caught_exception); | 2159 Handle<Object> exec_state = MakeExecutionState(&caught_exception); |
| 2175 Handle<Object> event_data; | 2160 Handle<Object> event_data; |
| 2176 if (!caught_exception) { | 2161 if (!caught_exception) { |
| 2177 event_data = MakeBreakEvent(exec_state, break_points_hit, | 2162 event_data = MakeBreakEvent(exec_state, break_points_hit, |
| 2178 &caught_exception); | 2163 &caught_exception); |
| 2179 } | 2164 } |
| 2180 // Bail out and don't call debugger if exception. | 2165 // Bail out and don't call debugger if exception. |
| 2181 if (caught_exception) { | 2166 if (caught_exception) { |
| 2182 return; | 2167 return; |
| 2183 } | 2168 } |
| 2184 | 2169 |
| 2185 // Process debug event. | 2170 // Process debug event. |
| 2186 ProcessDebugEvent(v8::Break, | 2171 ProcessDebugEvent(v8::Break, |
| 2187 Handle<JSObject>::cast(event_data), | 2172 Handle<JSObject>::cast(event_data), |
| 2188 auto_continue); | 2173 auto_continue); |
| 2189 } | 2174 } |
| 2190 | 2175 |
| 2191 | 2176 |
| 2192 void Debugger::OnBeforeCompile(Handle<Script> script) { | 2177 void Debugger::OnBeforeCompile(Handle<Script> script) { |
| 2193 ASSERT(Isolate::Current() == isolate_); | |
| 2194 HandleScope scope(isolate_); | 2178 HandleScope scope(isolate_); |
| 2195 | 2179 |
| 2196 // Bail out based on state or if there is no listener for this event | 2180 // Bail out based on state or if there is no listener for this event |
| 2197 if (isolate_->debug()->InDebugger()) return; | 2181 if (isolate_->debug()->InDebugger()) return; |
| 2198 if (compiling_natives()) return; | 2182 if (compiling_natives()) return; |
| 2199 if (!EventActive(v8::BeforeCompile)) return; | 2183 if (!EventActive(v8::BeforeCompile)) return; |
| 2200 | 2184 |
| 2201 // Enter the debugger. | 2185 // Enter the debugger. |
| 2202 EnterDebugger debugger; | 2186 EnterDebugger debugger; |
| 2203 if (debugger.FailedToEnter()) return; | 2187 if (debugger.FailedToEnter()) return; |
| 2204 | 2188 |
| 2205 // Create the event data object. | 2189 // Create the event data object. |
| 2206 bool caught_exception = false; | 2190 bool caught_exception = false; |
| 2207 Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception); | 2191 Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception); |
| 2208 // Bail out and don't call debugger if exception. | 2192 // Bail out and don't call debugger if exception. |
| 2209 if (caught_exception) { | 2193 if (caught_exception) { |
| 2210 return; | 2194 return; |
| 2211 } | 2195 } |
| 2212 | 2196 |
| 2213 // Process debug event. | 2197 // Process debug event. |
| 2214 ProcessDebugEvent(v8::BeforeCompile, | 2198 ProcessDebugEvent(v8::BeforeCompile, |
| 2215 Handle<JSObject>::cast(event_data), | 2199 Handle<JSObject>::cast(event_data), |
| 2216 true); | 2200 true); |
| 2217 } | 2201 } |
| 2218 | 2202 |
| 2219 | 2203 |
| 2220 // Handle debugger actions when a new script is compiled. | 2204 // Handle debugger actions when a new script is compiled. |
| 2221 void Debugger::OnAfterCompile(Handle<Script> script, | 2205 void Debugger::OnAfterCompile(Handle<Script> script, |
| 2222 AfterCompileFlags after_compile_flags) { | 2206 AfterCompileFlags after_compile_flags) { |
| 2223 ASSERT(Isolate::Current() == isolate_); | |
| 2224 HandleScope scope(isolate_); | 2207 HandleScope scope(isolate_); |
| 2225 Debug* debug = isolate_->debug(); | 2208 Debug* debug = isolate_->debug(); |
| 2226 | 2209 |
| 2227 // Add the newly compiled script to the script cache. | 2210 // Add the newly compiled script to the script cache. |
| 2228 debug->AddScriptToScriptCache(script); | 2211 debug->AddScriptToScriptCache(script); |
| 2229 | 2212 |
| 2230 // No more to do if not debugging. | 2213 // No more to do if not debugging. |
| 2231 if (!IsDebuggerActive()) return; | 2214 if (!IsDebuggerActive()) return; |
| 2232 | 2215 |
| 2233 // No compile events while compiling natives. | 2216 // No compile events while compiling natives. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2282 return; | 2265 return; |
| 2283 } | 2266 } |
| 2284 // Process debug event. | 2267 // Process debug event. |
| 2285 ProcessDebugEvent(v8::AfterCompile, | 2268 ProcessDebugEvent(v8::AfterCompile, |
| 2286 Handle<JSObject>::cast(event_data), | 2269 Handle<JSObject>::cast(event_data), |
| 2287 true); | 2270 true); |
| 2288 } | 2271 } |
| 2289 | 2272 |
| 2290 | 2273 |
| 2291 void Debugger::OnScriptCollected(int id) { | 2274 void Debugger::OnScriptCollected(int id) { |
| 2292 ASSERT(Isolate::Current() == isolate_); | |
| 2293 HandleScope scope(isolate_); | 2275 HandleScope scope(isolate_); |
| 2294 | 2276 |
| 2295 // No more to do if not debugging. | 2277 // No more to do if not debugging. |
| 2296 if (!IsDebuggerActive()) return; | 2278 if (!IsDebuggerActive()) return; |
| 2297 if (!Debugger::EventActive(v8::ScriptCollected)) return; | 2279 if (!Debugger::EventActive(v8::ScriptCollected)) return; |
| 2298 | 2280 |
| 2299 // Enter the debugger. | 2281 // Enter the debugger. |
| 2300 EnterDebugger debugger; | 2282 EnterDebugger debugger; |
| 2301 if (debugger.FailedToEnter()) return; | 2283 if (debugger.FailedToEnter()) return; |
| 2302 | 2284 |
| 2303 // Create the script collected state object. | 2285 // Create the script collected state object. |
| 2304 bool caught_exception = false; | 2286 bool caught_exception = false; |
| 2305 Handle<Object> event_data = MakeScriptCollectedEvent(id, | 2287 Handle<Object> event_data = MakeScriptCollectedEvent(id, |
| 2306 &caught_exception); | 2288 &caught_exception); |
| 2307 // Bail out and don't call debugger if exception. | 2289 // Bail out and don't call debugger if exception. |
| 2308 if (caught_exception) { | 2290 if (caught_exception) { |
| 2309 return; | 2291 return; |
| 2310 } | 2292 } |
| 2311 | 2293 |
| 2312 // Process debug event. | 2294 // Process debug event. |
| 2313 ProcessDebugEvent(v8::ScriptCollected, | 2295 ProcessDebugEvent(v8::ScriptCollected, |
| 2314 Handle<JSObject>::cast(event_data), | 2296 Handle<JSObject>::cast(event_data), |
| 2315 true); | 2297 true); |
| 2316 } | 2298 } |
| 2317 | 2299 |
| 2318 | 2300 |
| 2319 void Debugger::ProcessDebugEvent(v8::DebugEvent event, | 2301 void Debugger::ProcessDebugEvent(v8::DebugEvent event, |
| 2320 Handle<JSObject> event_data, | 2302 Handle<JSObject> event_data, |
| 2321 bool auto_continue) { | 2303 bool auto_continue) { |
| 2322 ASSERT(Isolate::Current() == isolate_); | |
| 2323 HandleScope scope(isolate_); | 2304 HandleScope scope(isolate_); |
| 2324 | 2305 |
| 2325 // Clear any pending debug break if this is a real break. | 2306 // Clear any pending debug break if this is a real break. |
| 2326 if (!auto_continue) { | 2307 if (!auto_continue) { |
| 2327 isolate_->debug()->clear_interrupt_pending(DEBUGBREAK); | 2308 isolate_->debug()->clear_interrupt_pending(DEBUGBREAK); |
| 2328 } | 2309 } |
| 2329 | 2310 |
| 2330 // Create the execution state. | 2311 // Create the execution state. |
| 2331 bool caught_exception = false; | 2312 bool caught_exception = false; |
| 2332 Handle<Object> exec_state = MakeExecutionState(&caught_exception); | 2313 Handle<Object> exec_state = MakeExecutionState(&caught_exception); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2388 event_listener_data_, | 2369 event_listener_data_, |
| 2389 client_data); | 2370 client_data); |
| 2390 callback(event_details); | 2371 callback(event_details); |
| 2391 } | 2372 } |
| 2392 | 2373 |
| 2393 | 2374 |
| 2394 void Debugger::CallJSEventCallback(v8::DebugEvent event, | 2375 void Debugger::CallJSEventCallback(v8::DebugEvent event, |
| 2395 Handle<Object> exec_state, | 2376 Handle<Object> exec_state, |
| 2396 Handle<Object> event_data) { | 2377 Handle<Object> event_data) { |
| 2397 ASSERT(event_listener_->IsJSFunction()); | 2378 ASSERT(event_listener_->IsJSFunction()); |
| 2398 ASSERT(Isolate::Current() == isolate_); | |
| 2399 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); | 2379 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); |
| 2400 | 2380 |
| 2401 // Invoke the JavaScript debug event listener. | 2381 // Invoke the JavaScript debug event listener. |
| 2402 const int argc = 4; | 2382 const int argc = 4; |
| 2403 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), | 2383 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), |
| 2404 exec_state.location(), | 2384 exec_state.location(), |
| 2405 Handle<Object>::cast(event_data).location(), | 2385 Handle<Object>::cast(event_data).location(), |
| 2406 event_listener_data_.location() }; | 2386 event_listener_data_.location() }; |
| 2407 bool caught_exception = false; | 2387 bool caught_exception = false; |
| 2408 Execution::TryCall(fun, isolate_->global(), argc, argv, &caught_exception); | 2388 Execution::TryCall(fun, isolate_->global(), argc, argv, &caught_exception); |
| 2409 // Silently ignore exceptions from debug event listeners. | 2389 // Silently ignore exceptions from debug event listeners. |
| 2410 } | 2390 } |
| 2411 | 2391 |
| 2412 | 2392 |
| 2413 Handle<Context> Debugger::GetDebugContext() { | 2393 Handle<Context> Debugger::GetDebugContext() { |
| 2414 ASSERT(Isolate::Current() == isolate_); | |
| 2415 never_unload_debugger_ = true; | 2394 never_unload_debugger_ = true; |
| 2416 EnterDebugger debugger; | 2395 EnterDebugger debugger; |
| 2417 return isolate_->debug()->debug_context(); | 2396 return isolate_->debug()->debug_context(); |
| 2418 } | 2397 } |
| 2419 | 2398 |
| 2420 | 2399 |
| 2421 void Debugger::UnloadDebugger() { | 2400 void Debugger::UnloadDebugger() { |
| 2422 ASSERT(Isolate::Current() == isolate_); | |
| 2423 Debug* debug = isolate_->debug(); | 2401 Debug* debug = isolate_->debug(); |
| 2424 | 2402 |
| 2425 // Make sure that there are no breakpoints left. | 2403 // Make sure that there are no breakpoints left. |
| 2426 debug->ClearAllBreakPoints(); | 2404 debug->ClearAllBreakPoints(); |
| 2427 | 2405 |
| 2428 // Unload the debugger if feasible. | 2406 // Unload the debugger if feasible. |
| 2429 if (!never_unload_debugger_) { | 2407 if (!never_unload_debugger_) { |
| 2430 debug->Unload(); | 2408 debug->Unload(); |
| 2431 } | 2409 } |
| 2432 | 2410 |
| 2433 // Clear the flag indicating that the debugger should be unloaded. | 2411 // Clear the flag indicating that the debugger should be unloaded. |
| 2434 debugger_unload_pending_ = false; | 2412 debugger_unload_pending_ = false; |
| 2435 } | 2413 } |
| 2436 | 2414 |
| 2437 | 2415 |
| 2438 void Debugger::NotifyMessageHandler(v8::DebugEvent event, | 2416 void Debugger::NotifyMessageHandler(v8::DebugEvent event, |
| 2439 Handle<JSObject> exec_state, | 2417 Handle<JSObject> exec_state, |
| 2440 Handle<JSObject> event_data, | 2418 Handle<JSObject> event_data, |
| 2441 bool auto_continue) { | 2419 bool auto_continue) { |
| 2442 ASSERT(Isolate::Current() == isolate_); | |
| 2443 HandleScope scope(isolate_); | 2420 HandleScope scope(isolate_); |
| 2444 | 2421 |
| 2445 if (!isolate_->debug()->Load()) return; | 2422 if (!isolate_->debug()->Load()) return; |
| 2446 | 2423 |
| 2447 // Process the individual events. | 2424 // Process the individual events. |
| 2448 bool sendEventMessage = false; | 2425 bool sendEventMessage = false; |
| 2449 switch (event) { | 2426 switch (event) { |
| 2450 case v8::Break: | 2427 case v8::Break: |
| 2451 case v8::BreakForCommand: | 2428 case v8::BreakForCommand: |
| 2452 sendEventMessage = !auto_continue; | 2429 sendEventMessage = !auto_continue; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2528 Debugger::host_dispatch_handler_(); | 2505 Debugger::host_dispatch_handler_(); |
| 2529 continue; | 2506 continue; |
| 2530 } | 2507 } |
| 2531 } else { | 2508 } else { |
| 2532 // In case there is no host dispatch - just wait. | 2509 // In case there is no host dispatch - just wait. |
| 2533 command_received_->Wait(); | 2510 command_received_->Wait(); |
| 2534 } | 2511 } |
| 2535 | 2512 |
| 2536 // Get the command from the queue. | 2513 // Get the command from the queue. |
| 2537 CommandMessage command = command_queue_.Get(); | 2514 CommandMessage command = command_queue_.Get(); |
| 2538 LOGGER->DebugTag("Got request from command queue, in interactive loop."); | 2515 isolate_->logger()->DebugTag( |
| 2516 "Got request from command queue, in interactive loop."); | |
| 2539 if (!Debugger::IsDebuggerActive()) { | 2517 if (!Debugger::IsDebuggerActive()) { |
| 2540 // Delete command text and user data. | 2518 // Delete command text and user data. |
| 2541 command.Dispose(); | 2519 command.Dispose(); |
| 2542 return; | 2520 return; |
| 2543 } | 2521 } |
| 2544 | 2522 |
| 2545 // Invoke JavaScript to process the debug request. | 2523 // Invoke JavaScript to process the debug request. |
| 2546 v8::Local<v8::String> fun_name; | 2524 v8::Local<v8::String> fun_name; |
| 2547 v8::Local<v8::Function> fun; | 2525 v8::Local<v8::Function> fun; |
| 2548 v8::Local<v8::Value> request; | 2526 v8::Local<v8::Value> request; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2602 // and there are no more commands queued. | 2580 // and there are no more commands queued. |
| 2603 if (running && !HasCommands()) { | 2581 if (running && !HasCommands()) { |
| 2604 return; | 2582 return; |
| 2605 } | 2583 } |
| 2606 } | 2584 } |
| 2607 } | 2585 } |
| 2608 | 2586 |
| 2609 | 2587 |
| 2610 void Debugger::SetEventListener(Handle<Object> callback, | 2588 void Debugger::SetEventListener(Handle<Object> callback, |
| 2611 Handle<Object> data) { | 2589 Handle<Object> data) { |
| 2612 ASSERT(Isolate::Current() == isolate_); | |
| 2613 HandleScope scope(isolate_); | 2590 HandleScope scope(isolate_); |
| 2614 GlobalHandles* global_handles = isolate_->global_handles(); | 2591 GlobalHandles* global_handles = isolate_->global_handles(); |
| 2615 | 2592 |
| 2616 // Clear the global handles for the event listener and the event listener data | 2593 // Clear the global handles for the event listener and the event listener data |
| 2617 // object. | 2594 // object. |
| 2618 if (!event_listener_.is_null()) { | 2595 if (!event_listener_.is_null()) { |
| 2619 global_handles->Destroy( | 2596 global_handles->Destroy( |
| 2620 reinterpret_cast<Object**>(event_listener_.location())); | 2597 reinterpret_cast<Object**>(event_listener_.location())); |
| 2621 event_listener_ = Handle<Object>(); | 2598 event_listener_ = Handle<Object>(); |
| 2622 } | 2599 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2636 } | 2613 } |
| 2637 event_listener_data_ = Handle<Object>::cast( | 2614 event_listener_data_ = Handle<Object>::cast( |
| 2638 global_handles->Create(*data)); | 2615 global_handles->Create(*data)); |
| 2639 } | 2616 } |
| 2640 | 2617 |
| 2641 ListenersChanged(); | 2618 ListenersChanged(); |
| 2642 } | 2619 } |
| 2643 | 2620 |
| 2644 | 2621 |
| 2645 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) { | 2622 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) { |
| 2646 ASSERT(Isolate::Current() == isolate_); | |
| 2647 ScopedLock with(debugger_access_); | 2623 ScopedLock with(debugger_access_); |
| 2648 | 2624 |
| 2649 message_handler_ = handler; | 2625 message_handler_ = handler; |
| 2650 ListenersChanged(); | 2626 ListenersChanged(); |
| 2651 if (handler == NULL) { | 2627 if (handler == NULL) { |
| 2652 // Send an empty command to the debugger if in a break to make JavaScript | 2628 // Send an empty command to the debugger if in a break to make JavaScript |
| 2653 // run again if the debugger is closed. | 2629 // run again if the debugger is closed. |
| 2654 if (isolate_->debug()->InDebugger()) { | 2630 if (isolate_->debug()->InDebugger()) { |
| 2655 ProcessCommand(Vector<const uint16_t>::empty()); | 2631 ProcessCommand(Vector<const uint16_t>::empty()); |
| 2656 } | 2632 } |
| 2657 } | 2633 } |
| 2658 } | 2634 } |
| 2659 | 2635 |
| 2660 | 2636 |
| 2661 void Debugger::ListenersChanged() { | 2637 void Debugger::ListenersChanged() { |
| 2662 ASSERT(Isolate::Current() == isolate_); | |
| 2663 if (IsDebuggerActive()) { | 2638 if (IsDebuggerActive()) { |
| 2664 // Disable the compilation cache when the debugger is active. | 2639 // Disable the compilation cache when the debugger is active. |
| 2665 isolate_->compilation_cache()->Disable(); | 2640 isolate_->compilation_cache()->Disable(); |
|
Vitaly Repeshko
2011/06/10 08:18:50
As we discussed this is actually unsafe. Listeners
mnaganov (inactive)
2011/06/10 09:31:32
http://code.google.com/p/v8/issues/detail?id=1448
| |
| 2666 debugger_unload_pending_ = false; | 2641 debugger_unload_pending_ = false; |
| 2667 } else { | 2642 } else { |
| 2668 isolate_->compilation_cache()->Enable(); | 2643 isolate_->compilation_cache()->Enable(); |
| 2669 // Unload the debugger if event listener and message handler cleared. | 2644 // Unload the debugger if event listener and message handler cleared. |
| 2670 // Schedule this for later, because we may be in non-V8 thread. | 2645 // Schedule this for later, because we may be in non-V8 thread. |
| 2671 debugger_unload_pending_ = true; | 2646 debugger_unload_pending_ = true; |
| 2672 } | 2647 } |
| 2673 } | 2648 } |
| 2674 | 2649 |
| 2675 | 2650 |
| 2676 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, | 2651 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, |
| 2677 int period) { | 2652 int period) { |
| 2678 ASSERT(Isolate::Current() == isolate_); | |
| 2679 host_dispatch_handler_ = handler; | 2653 host_dispatch_handler_ = handler; |
| 2680 host_dispatch_micros_ = period * 1000; | 2654 host_dispatch_micros_ = period * 1000; |
| 2681 } | 2655 } |
| 2682 | 2656 |
| 2683 | 2657 |
| 2684 void Debugger::SetDebugMessageDispatchHandler( | 2658 void Debugger::SetDebugMessageDispatchHandler( |
| 2685 v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) { | 2659 v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) { |
| 2686 ASSERT(Isolate::Current() == isolate_); | |
| 2687 ScopedLock with(dispatch_handler_access_); | 2660 ScopedLock with(dispatch_handler_access_); |
| 2688 debug_message_dispatch_handler_ = handler; | 2661 debug_message_dispatch_handler_ = handler; |
| 2689 | 2662 |
| 2690 if (provide_locker && message_dispatch_helper_thread_ == NULL) { | 2663 if (provide_locker && message_dispatch_helper_thread_ == NULL) { |
| 2691 message_dispatch_helper_thread_ = new MessageDispatchHelperThread(isolate_); | 2664 message_dispatch_helper_thread_ = new MessageDispatchHelperThread(isolate_); |
| 2692 message_dispatch_helper_thread_->Start(); | 2665 message_dispatch_helper_thread_->Start(); |
| 2693 } | 2666 } |
| 2694 } | 2667 } |
| 2695 | 2668 |
| 2696 | 2669 |
| 2697 // Calls the registered debug message handler. This callback is part of the | 2670 // Calls the registered debug message handler. This callback is part of the |
| 2698 // public API. | 2671 // public API. |
| 2699 void Debugger::InvokeMessageHandler(MessageImpl message) { | 2672 void Debugger::InvokeMessageHandler(MessageImpl message) { |
| 2700 ASSERT(Isolate::Current() == isolate_); | |
| 2701 ScopedLock with(debugger_access_); | 2673 ScopedLock with(debugger_access_); |
| 2702 | 2674 |
| 2703 if (message_handler_ != NULL) { | 2675 if (message_handler_ != NULL) { |
| 2704 message_handler_(message); | 2676 message_handler_(message); |
| 2705 } | 2677 } |
| 2706 } | 2678 } |
| 2707 | 2679 |
| 2708 | 2680 |
| 2709 // Puts a command coming from the public API on the queue. Creates | 2681 // Puts a command coming from the public API on the queue. Creates |
| 2710 // a copy of the command string managed by the debugger. Up to this | 2682 // a copy of the command string managed by the debugger. Up to this |
| 2711 // point, the command data was managed by the API client. Called | 2683 // point, the command data was managed by the API client. Called |
| 2712 // by the API client thread. | 2684 // by the API client thread. |
| 2713 void Debugger::ProcessCommand(Vector<const uint16_t> command, | 2685 void Debugger::ProcessCommand(Vector<const uint16_t> command, |
| 2714 v8::Debug::ClientData* client_data) { | 2686 v8::Debug::ClientData* client_data) { |
| 2715 ASSERT(Isolate::Current() == isolate_); | |
| 2716 // Need to cast away const. | 2687 // Need to cast away const. |
| 2717 CommandMessage message = CommandMessage::New( | 2688 CommandMessage message = CommandMessage::New( |
| 2718 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), | 2689 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), |
| 2719 command.length()), | 2690 command.length()), |
| 2720 client_data); | 2691 client_data); |
| 2721 LOGGER->DebugTag("Put command on command_queue."); | 2692 isolate_->logger()->DebugTag("Put command on command_queue."); |
| 2722 command_queue_.Put(message); | 2693 command_queue_.Put(message); |
| 2723 command_received_->Signal(); | 2694 command_received_->Signal(); |
| 2724 | 2695 |
| 2725 // Set the debug command break flag to have the command processed. | 2696 // Set the debug command break flag to have the command processed. |
| 2726 if (!isolate_->debug()->InDebugger()) { | 2697 if (!isolate_->debug()->InDebugger()) { |
| 2727 isolate_->stack_guard()->DebugCommand(); | 2698 isolate_->stack_guard()->DebugCommand(); |
| 2728 } | 2699 } |
| 2729 | 2700 |
| 2730 MessageDispatchHelperThread* dispatch_thread; | 2701 MessageDispatchHelperThread* dispatch_thread; |
| 2731 { | 2702 { |
| 2732 ScopedLock with(dispatch_handler_access_); | 2703 ScopedLock with(dispatch_handler_access_); |
| 2733 dispatch_thread = message_dispatch_helper_thread_; | 2704 dispatch_thread = message_dispatch_helper_thread_; |
| 2734 } | 2705 } |
| 2735 | 2706 |
| 2736 if (dispatch_thread == NULL) { | 2707 if (dispatch_thread == NULL) { |
| 2737 CallMessageDispatchHandler(); | 2708 CallMessageDispatchHandler(); |
| 2738 } else { | 2709 } else { |
| 2739 dispatch_thread->Schedule(); | 2710 dispatch_thread->Schedule(); |
| 2740 } | 2711 } |
| 2741 } | 2712 } |
| 2742 | 2713 |
| 2743 | 2714 |
| 2744 bool Debugger::HasCommands() { | 2715 bool Debugger::HasCommands() { |
| 2745 ASSERT(Isolate::Current() == isolate_); | |
| 2746 return !command_queue_.IsEmpty(); | 2716 return !command_queue_.IsEmpty(); |
| 2747 } | 2717 } |
| 2748 | 2718 |
| 2749 | 2719 |
| 2750 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { | 2720 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { |
| 2751 ASSERT(Isolate::Current() == isolate_); | |
| 2752 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); | 2721 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); |
| 2753 event_command_queue_.Put(message); | 2722 event_command_queue_.Put(message); |
| 2754 | 2723 |
| 2755 // Set the debug command break flag to have the command processed. | 2724 // Set the debug command break flag to have the command processed. |
| 2756 if (!isolate_->debug()->InDebugger()) { | 2725 if (!isolate_->debug()->InDebugger()) { |
| 2757 isolate_->stack_guard()->DebugCommand(); | 2726 isolate_->stack_guard()->DebugCommand(); |
| 2758 } | 2727 } |
| 2759 } | 2728 } |
| 2760 | 2729 |
| 2761 | 2730 |
| 2762 bool Debugger::IsDebuggerActive() { | 2731 bool Debugger::IsDebuggerActive() { |
| 2763 ASSERT(Isolate::Current() == isolate_); | |
| 2764 ScopedLock with(debugger_access_); | 2732 ScopedLock with(debugger_access_); |
| 2765 | 2733 |
| 2766 return message_handler_ != NULL || !event_listener_.is_null(); | 2734 return message_handler_ != NULL || !event_listener_.is_null(); |
| 2767 } | 2735 } |
| 2768 | 2736 |
| 2769 | 2737 |
| 2770 Handle<Object> Debugger::Call(Handle<JSFunction> fun, | 2738 Handle<Object> Debugger::Call(Handle<JSFunction> fun, |
| 2771 Handle<Object> data, | 2739 Handle<Object> data, |
| 2772 bool* pending_exception) { | 2740 bool* pending_exception) { |
| 2773 ASSERT(Isolate::Current() == isolate_); | |
| 2774 // When calling functions in the debugger prevent it from beeing unloaded. | 2741 // When calling functions in the debugger prevent it from beeing unloaded. |
| 2775 Debugger::never_unload_debugger_ = true; | 2742 Debugger::never_unload_debugger_ = true; |
| 2776 | 2743 |
| 2777 // Enter the debugger. | 2744 // Enter the debugger. |
| 2778 EnterDebugger debugger; | 2745 EnterDebugger debugger; |
| 2779 if (debugger.FailedToEnter()) { | 2746 if (debugger.FailedToEnter()) { |
| 2780 return isolate_->factory()->undefined_value(); | 2747 return isolate_->factory()->undefined_value(); |
| 2781 } | 2748 } |
| 2782 | 2749 |
| 2783 // Create the execution state. | 2750 // Create the execution state. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2813 // Provide stub message handler; V8 auto-continues each suspend | 2780 // Provide stub message handler; V8 auto-continues each suspend |
| 2814 // when there is no message handler; we doesn't need it. | 2781 // when there is no message handler; we doesn't need it. |
| 2815 // Once become suspended, V8 will stay so indefinitely long, until remote | 2782 // Once become suspended, V8 will stay so indefinitely long, until remote |
| 2816 // debugger connects and issues "continue" command. | 2783 // debugger connects and issues "continue" command. |
| 2817 Debugger::message_handler_ = StubMessageHandler2; | 2784 Debugger::message_handler_ = StubMessageHandler2; |
| 2818 v8::Debug::DebugBreak(); | 2785 v8::Debug::DebugBreak(); |
| 2819 } | 2786 } |
| 2820 | 2787 |
| 2821 if (Socket::Setup()) { | 2788 if (Socket::Setup()) { |
| 2822 if (agent_ == NULL) { | 2789 if (agent_ == NULL) { |
| 2823 agent_ = new DebuggerAgent(isolate_, name, port); | 2790 agent_ = new DebuggerAgent(name, port); |
| 2824 agent_->Start(); | 2791 agent_->Start(); |
| 2825 } | 2792 } |
| 2826 return true; | 2793 return true; |
| 2827 } | 2794 } |
| 2828 | 2795 |
| 2829 return false; | 2796 return false; |
| 2830 } | 2797 } |
| 2831 | 2798 |
| 2832 | 2799 |
| 2833 void Debugger::StopAgent() { | 2800 void Debugger::StopAgent() { |
| 2834 ASSERT(Isolate::Current() == isolate_); | 2801 ASSERT(Isolate::Current() == isolate_); |
| 2835 if (agent_ != NULL) { | 2802 if (agent_ != NULL) { |
| 2836 agent_->Shutdown(); | 2803 agent_->Shutdown(); |
| 2837 agent_->Join(); | 2804 agent_->Join(); |
| 2838 delete agent_; | 2805 delete agent_; |
| 2839 agent_ = NULL; | 2806 agent_ = NULL; |
| 2840 } | 2807 } |
| 2841 } | 2808 } |
| 2842 | 2809 |
| 2843 | 2810 |
| 2844 void Debugger::WaitForAgent() { | 2811 void Debugger::WaitForAgent() { |
| 2845 ASSERT(Isolate::Current() == isolate_); | 2812 ASSERT(Isolate::Current() == isolate_); |
| 2846 if (agent_ != NULL) | 2813 if (agent_ != NULL) |
| 2847 agent_->WaitUntilListening(); | 2814 agent_->WaitUntilListening(); |
| 2848 } | 2815 } |
| 2849 | 2816 |
| 2850 | 2817 |
| 2851 void Debugger::CallMessageDispatchHandler() { | 2818 void Debugger::CallMessageDispatchHandler() { |
| 2852 ASSERT(Isolate::Current() == isolate_); | |
| 2853 v8::Debug::DebugMessageDispatchHandler handler; | 2819 v8::Debug::DebugMessageDispatchHandler handler; |
| 2854 { | 2820 { |
| 2855 ScopedLock with(dispatch_handler_access_); | 2821 ScopedLock with(dispatch_handler_access_); |
| 2856 handler = Debugger::debug_message_dispatch_handler_; | 2822 handler = Debugger::debug_message_dispatch_handler_; |
| 2857 } | 2823 } |
| 2858 if (handler != NULL) { | 2824 if (handler != NULL) { |
| 2859 handler(); | 2825 handler(); |
| 2860 } | 2826 } |
| 2861 } | 2827 } |
| 2862 | 2828 |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3076 } | 3042 } |
| 3077 CommandMessage* array_to_free = messages_; | 3043 CommandMessage* array_to_free = messages_; |
| 3078 *this = new_queue; | 3044 *this = new_queue; |
| 3079 new_queue.messages_ = array_to_free; | 3045 new_queue.messages_ = array_to_free; |
| 3080 // Make the new_queue empty so that it doesn't call Dispose on any messages. | 3046 // Make the new_queue empty so that it doesn't call Dispose on any messages. |
| 3081 new_queue.start_ = new_queue.end_; | 3047 new_queue.start_ = new_queue.end_; |
| 3082 // Automatic destructor called on new_queue, freeing array_to_free. | 3048 // Automatic destructor called on new_queue, freeing array_to_free. |
| 3083 } | 3049 } |
| 3084 | 3050 |
| 3085 | 3051 |
| 3086 LockingCommandMessageQueue::LockingCommandMessageQueue(int size) | 3052 LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size) |
| 3087 : queue_(size) { | 3053 : logger_(logger), queue_(size) { |
| 3088 lock_ = OS::CreateMutex(); | 3054 lock_ = OS::CreateMutex(); |
| 3089 } | 3055 } |
| 3090 | 3056 |
| 3091 | 3057 |
| 3092 LockingCommandMessageQueue::~LockingCommandMessageQueue() { | 3058 LockingCommandMessageQueue::~LockingCommandMessageQueue() { |
| 3093 delete lock_; | 3059 delete lock_; |
| 3094 } | 3060 } |
| 3095 | 3061 |
| 3096 | 3062 |
| 3097 bool LockingCommandMessageQueue::IsEmpty() const { | 3063 bool LockingCommandMessageQueue::IsEmpty() const { |
| 3098 ScopedLock sl(lock_); | 3064 ScopedLock sl(lock_); |
| 3099 return queue_.IsEmpty(); | 3065 return queue_.IsEmpty(); |
| 3100 } | 3066 } |
| 3101 | 3067 |
| 3102 | 3068 |
| 3103 CommandMessage LockingCommandMessageQueue::Get() { | 3069 CommandMessage LockingCommandMessageQueue::Get() { |
| 3104 ScopedLock sl(lock_); | 3070 ScopedLock sl(lock_); |
| 3105 CommandMessage result = queue_.Get(); | 3071 CommandMessage result = queue_.Get(); |
| 3106 LOGGER->DebugEvent("Get", result.text()); | 3072 logger_->DebugEvent("Get", result.text()); |
| 3107 return result; | 3073 return result; |
| 3108 } | 3074 } |
| 3109 | 3075 |
| 3110 | 3076 |
| 3111 void LockingCommandMessageQueue::Put(const CommandMessage& message) { | 3077 void LockingCommandMessageQueue::Put(const CommandMessage& message) { |
| 3112 ScopedLock sl(lock_); | 3078 ScopedLock sl(lock_); |
| 3113 queue_.Put(message); | 3079 queue_.Put(message); |
| 3114 LOGGER->DebugEvent("Put", message.text()); | 3080 logger_->DebugEvent("Put", message.text()); |
| 3115 } | 3081 } |
| 3116 | 3082 |
| 3117 | 3083 |
| 3118 void LockingCommandMessageQueue::Clear() { | 3084 void LockingCommandMessageQueue::Clear() { |
| 3119 ScopedLock sl(lock_); | 3085 ScopedLock sl(lock_); |
| 3120 queue_.Clear(); | 3086 queue_.Clear(); |
| 3121 } | 3087 } |
| 3122 | 3088 |
| 3123 | 3089 |
| 3124 MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate) | 3090 MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate) |
| 3125 : Thread(isolate, "v8:MsgDispHelpr"), | 3091 : Thread("v8:MsgDispHelpr"), |
| 3126 sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()), | 3092 sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()), |
| 3127 already_signalled_(false) { | 3093 already_signalled_(false) { |
| 3128 } | 3094 } |
| 3129 | 3095 |
| 3130 | 3096 |
| 3131 MessageDispatchHelperThread::~MessageDispatchHelperThread() { | 3097 MessageDispatchHelperThread::~MessageDispatchHelperThread() { |
| 3132 delete mutex_; | 3098 delete mutex_; |
| 3133 delete sem_; | 3099 delete sem_; |
| 3134 } | 3100 } |
| 3135 | 3101 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 3156 { | 3122 { |
| 3157 Locker locker; | 3123 Locker locker; |
| 3158 Isolate::Current()->debugger()->CallMessageDispatchHandler(); | 3124 Isolate::Current()->debugger()->CallMessageDispatchHandler(); |
| 3159 } | 3125 } |
| 3160 } | 3126 } |
| 3161 } | 3127 } |
| 3162 | 3128 |
| 3163 #endif // ENABLE_DEBUGGER_SUPPORT | 3129 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3164 | 3130 |
| 3165 } } // namespace v8::internal | 3131 } } // namespace v8::internal |
| OLD | NEW |