| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/debugger.h" | 5 #include "vm/debugger.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| (...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 } | 1386 } |
| 1387 // Also disable any optimized implicit closure functions. | 1387 // Also disable any optimized implicit closure functions. |
| 1388 if (function.HasImplicitClosureFunction()) { | 1388 if (function.HasImplicitClosureFunction()) { |
| 1389 function = function.ImplicitClosureFunction(); | 1389 function = function.ImplicitClosureFunction(); |
| 1390 if (function.HasOptimizedCode()) { | 1390 if (function.HasOptimizedCode()) { |
| 1391 function.SwitchToUnoptimizedCode(); | 1391 function.SwitchToUnoptimizedCode(); |
| 1392 } | 1392 } |
| 1393 } | 1393 } |
| 1394 } | 1394 } |
| 1395 } | 1395 } |
| 1396 | |
| 1397 // Disable other optimized closure functions. | |
| 1398 closures = cls.closures(); | |
| 1399 if (!closures.IsNull()) { | |
| 1400 intptr_t num_closures = closures.Length(); | |
| 1401 for (intptr_t pos = 0; pos < num_closures; pos++) { | |
| 1402 function ^= closures.At(pos); | |
| 1403 ASSERT(!function.IsNull()); | |
| 1404 if (function.HasOptimizedCode()) { | |
| 1405 function.SwitchToUnoptimizedCode(); | |
| 1406 } | |
| 1407 } | |
| 1408 } | |
| 1409 } | 1396 } |
| 1410 } | 1397 } |
| 1398 |
| 1399 // Disable optimized closure functions. |
| 1400 closures = isolate_->object_store()->closure_functions(); |
| 1401 const intptr_t num_closures = closures.Length(); |
| 1402 for (intptr_t pos = 0; pos < num_closures; pos++) { |
| 1403 function ^= closures.At(pos); |
| 1404 ASSERT(!function.IsNull()); |
| 1405 if (function.HasOptimizedCode()) { |
| 1406 function.SwitchToUnoptimizedCode(); |
| 1407 } |
| 1408 } |
| 1411 } | 1409 } |
| 1412 | 1410 |
| 1413 | 1411 |
| 1414 void Debugger::SignalBpResolved(Breakpoint* bpt) { | 1412 void Debugger::SignalBpResolved(Breakpoint* bpt) { |
| 1415 if (HasEventHandler() && !bpt->IsSingleShot()) { | 1413 if (HasEventHandler() && !bpt->IsSingleShot()) { |
| 1416 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved); | 1414 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved); |
| 1417 event.set_breakpoint(bpt); | 1415 event.set_breakpoint(bpt); |
| 1418 InvokeEventHandler(&event); | 1416 InvokeEventHandler(&event); |
| 1419 } | 1417 } |
| 1420 } | 1418 } |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1874 void Debugger::FindCompiledFunctions(const Script& script, | 1872 void Debugger::FindCompiledFunctions(const Script& script, |
| 1875 intptr_t start_pos, | 1873 intptr_t start_pos, |
| 1876 intptr_t end_pos, | 1874 intptr_t end_pos, |
| 1877 GrowableObjectArray* function_list) { | 1875 GrowableObjectArray* function_list) { |
| 1878 Zone* zone = Thread::Current()->zone(); | 1876 Zone* zone = Thread::Current()->zone(); |
| 1879 Class& cls = Class::Handle(zone); | 1877 Class& cls = Class::Handle(zone); |
| 1880 Array& functions = Array::Handle(zone); | 1878 Array& functions = Array::Handle(zone); |
| 1881 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); | 1879 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
| 1882 Function& function = Function::Handle(zone); | 1880 Function& function = Function::Handle(zone); |
| 1883 | 1881 |
| 1882 closures = isolate_->object_store()->closure_functions(); |
| 1883 const intptr_t num_closures = closures.Length(); |
| 1884 for (intptr_t pos = 0; pos < num_closures; pos++) { |
| 1885 function ^= closures.At(pos); |
| 1886 ASSERT(!function.IsNull()); |
| 1887 if ((function.token_pos() == start_pos) |
| 1888 && (function.end_token_pos() == end_pos) |
| 1889 && (function.script() == script.raw())) { |
| 1890 if (function.HasCode() && function.is_debuggable()) { |
| 1891 function_list->Add(function); |
| 1892 } |
| 1893 if (function.HasImplicitClosureFunction()) { |
| 1894 function = function.ImplicitClosureFunction(); |
| 1895 if (function.HasCode() && function.is_debuggable()) { |
| 1896 function_list->Add(function); |
| 1897 } |
| 1898 } |
| 1899 } |
| 1900 } |
| 1901 |
| 1884 const ClassTable& class_table = *isolate_->class_table(); | 1902 const ClassTable& class_table = *isolate_->class_table(); |
| 1885 const intptr_t num_classes = class_table.NumCids(); | 1903 const intptr_t num_classes = class_table.NumCids(); |
| 1886 for (intptr_t i = 1; i < num_classes; i++) { | 1904 for (intptr_t i = 1; i < num_classes; i++) { |
| 1887 if (class_table.HasValidClassAt(i)) { | 1905 if (class_table.HasValidClassAt(i)) { |
| 1888 cls = class_table.At(i); | 1906 cls = class_table.At(i); |
| 1889 // If the class is not finalized, e.g. if it hasn't been parsed | 1907 // If the class is not finalized, e.g. if it hasn't been parsed |
| 1890 // yet entirely, we can ignore it. If it contains a function with | 1908 // yet entirely, we can ignore it. If it contains a function with |
| 1891 // an unresolved breakpoint, we will detect it if and when the | 1909 // an unresolved breakpoint, we will detect it if and when the |
| 1892 // function gets compiled. | 1910 // function gets compiled. |
| 1893 if (!cls.is_finalized()) { | 1911 if (!cls.is_finalized()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1912 } | 1930 } |
| 1913 if (function.HasImplicitClosureFunction()) { | 1931 if (function.HasImplicitClosureFunction()) { |
| 1914 function = function.ImplicitClosureFunction(); | 1932 function = function.ImplicitClosureFunction(); |
| 1915 if (function.HasCode() && function.is_debuggable()) { | 1933 if (function.HasCode() && function.is_debuggable()) { |
| 1916 function_list->Add(function); | 1934 function_list->Add(function); |
| 1917 } | 1935 } |
| 1918 } | 1936 } |
| 1919 } | 1937 } |
| 1920 } | 1938 } |
| 1921 } | 1939 } |
| 1922 closures = cls.closures(); | |
| 1923 if (!closures.IsNull()) { | |
| 1924 const intptr_t num_closures = closures.Length(); | |
| 1925 for (intptr_t pos = 0; pos < num_closures; pos++) { | |
| 1926 function ^= closures.At(pos); | |
| 1927 ASSERT(!function.IsNull()); | |
| 1928 if ((function.token_pos() == start_pos) | |
| 1929 && (function.end_token_pos() == end_pos) | |
| 1930 && (function.script() == script.raw())) { | |
| 1931 if (function.HasCode() && function.is_debuggable()) { | |
| 1932 function_list->Add(function); | |
| 1933 } | |
| 1934 if (function.HasImplicitClosureFunction()) { | |
| 1935 function = function.ImplicitClosureFunction(); | |
| 1936 if (function.HasCode() && function.is_debuggable()) { | |
| 1937 function_list->Add(function); | |
| 1938 } | |
| 1939 } | |
| 1940 } | |
| 1941 } | |
| 1942 } | |
| 1943 } | 1940 } |
| 1944 } | 1941 } |
| 1945 } | 1942 } |
| 1946 | 1943 |
| 1947 | 1944 |
| 1948 static void SelectBestFit(Function* best_fit, Function* func) { | 1945 static void SelectBestFit(Function* best_fit, Function* func) { |
| 1949 if (best_fit->IsNull()) { | 1946 if (best_fit->IsNull()) { |
| 1950 *best_fit = func->raw(); | 1947 *best_fit = func->raw(); |
| 1951 } else { | 1948 } else { |
| 1952 if ((func->token_pos() > best_fit->token_pos()) && | 1949 if ((func->token_pos() > best_fit->token_pos()) && |
| 1953 ((func->end_token_pos() <= best_fit->end_token_pos()))) { | 1950 ((func->end_token_pos() <= best_fit->end_token_pos()))) { |
| 1954 *best_fit = func->raw(); | 1951 *best_fit = func->raw(); |
| 1955 } | 1952 } |
| 1956 } | 1953 } |
| 1957 } | 1954 } |
| 1958 | 1955 |
| 1959 | 1956 |
| 1960 RawFunction* Debugger::FindBestFit(const Script& script, | 1957 RawFunction* Debugger::FindBestFit(const Script& script, |
| 1961 intptr_t token_pos) { | 1958 intptr_t token_pos) { |
| 1962 Zone* zone = Thread::Current()->zone(); | 1959 Zone* zone = Thread::Current()->zone(); |
| 1963 Class& cls = Class::Handle(zone); | 1960 Class& cls = Class::Handle(zone); |
| 1964 Array& functions = Array::Handle(zone); | 1961 Array& functions = Array::Handle(zone); |
| 1965 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); | 1962 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
| 1966 Function& function = Function::Handle(zone); | 1963 Function& function = Function::Handle(zone); |
| 1967 Function& best_fit = Function::Handle(zone); | 1964 Function& best_fit = Function::Handle(zone); |
| 1968 Error& error = Error::Handle(zone); | 1965 Error& error = Error::Handle(zone); |
| 1969 | 1966 |
| 1967 closures = isolate_->object_store()->closure_functions(); |
| 1968 const intptr_t num_closures = closures.Length(); |
| 1969 for (intptr_t i = 0; i < num_closures; i++) { |
| 1970 function ^= closures.At(i); |
| 1971 if (FunctionContains(function, script, token_pos)) { |
| 1972 SelectBestFit(&best_fit, &function); |
| 1973 } |
| 1974 } |
| 1975 |
| 1970 const ClassTable& class_table = *isolate_->class_table(); | 1976 const ClassTable& class_table = *isolate_->class_table(); |
| 1971 const intptr_t num_classes = class_table.NumCids(); | 1977 const intptr_t num_classes = class_table.NumCids(); |
| 1972 for (intptr_t i = 1; i < num_classes; i++) { | 1978 for (intptr_t i = 1; i < num_classes; i++) { |
| 1973 if (class_table.HasValidClassAt(i)) { | 1979 if (class_table.HasValidClassAt(i)) { |
| 1974 cls = class_table.At(i); | 1980 cls = class_table.At(i); |
| 1975 // Note: if this class has been parsed and finalized already, | 1981 // Note: if this class has been parsed and finalized already, |
| 1976 // we need to check the functions of this class even if | 1982 // we need to check the functions of this class even if |
| 1977 // it is defined in a differenct 'script'. There could | 1983 // it is defined in a differenct 'script'. There could |
| 1978 // be mixin functions from the given script in this class. | 1984 // be mixin functions from the given script in this class. |
| 1979 // However, if this class is not parsed yet (not finalized), | 1985 // However, if this class is not parsed yet (not finalized), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1994 if (!functions.IsNull()) { | 2000 if (!functions.IsNull()) { |
| 1995 const intptr_t num_functions = functions.Length(); | 2001 const intptr_t num_functions = functions.Length(); |
| 1996 for (intptr_t pos = 0; pos < num_functions; pos++) { | 2002 for (intptr_t pos = 0; pos < num_functions; pos++) { |
| 1997 function ^= functions.At(pos); | 2003 function ^= functions.At(pos); |
| 1998 ASSERT(!function.IsNull()); | 2004 ASSERT(!function.IsNull()); |
| 1999 if (FunctionContains(function, script, token_pos)) { | 2005 if (FunctionContains(function, script, token_pos)) { |
| 2000 SelectBestFit(&best_fit, &function); | 2006 SelectBestFit(&best_fit, &function); |
| 2001 } | 2007 } |
| 2002 } | 2008 } |
| 2003 } | 2009 } |
| 2004 | |
| 2005 closures = cls.closures(); | |
| 2006 if (!closures.IsNull()) { | |
| 2007 const intptr_t num_closures = closures.Length(); | |
| 2008 for (intptr_t pos = 0; pos < num_closures; pos++) { | |
| 2009 function ^= closures.At(pos); | |
| 2010 ASSERT(!function.IsNull()); | |
| 2011 if (FunctionContains(function, script, token_pos)) { | |
| 2012 SelectBestFit(&best_fit, &function); | |
| 2013 } | |
| 2014 } | |
| 2015 } | |
| 2016 } | 2010 } |
| 2017 } | 2011 } |
| 2018 return best_fit.raw(); | 2012 return best_fit.raw(); |
| 2019 } | 2013 } |
| 2020 | 2014 |
| 2021 | 2015 |
| 2022 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, | 2016 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, |
| 2023 intptr_t token_pos, | 2017 intptr_t token_pos, |
| 2024 intptr_t last_token_pos, | 2018 intptr_t last_token_pos, |
| 2025 intptr_t requested_line, | 2019 intptr_t requested_line, |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2822 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); | 2816 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); |
| 2823 creation_message_sent_ = true; | 2817 creation_message_sent_ = true; |
| 2824 } | 2818 } |
| 2825 } | 2819 } |
| 2826 | 2820 |
| 2827 | 2821 |
| 2828 // Return innermost closure contained in 'function' that contains | 2822 // Return innermost closure contained in 'function' that contains |
| 2829 // the given token position. | 2823 // the given token position. |
| 2830 RawFunction* Debugger::FindInnermostClosure(const Function& function, | 2824 RawFunction* Debugger::FindInnermostClosure(const Function& function, |
| 2831 intptr_t token_pos) { | 2825 intptr_t token_pos) { |
| 2832 const Class& owner = Class::Handle(function.Owner()); | |
| 2833 if (owner.closures() == GrowableObjectArray::null()) { | |
| 2834 return Function::null(); | |
| 2835 } | |
| 2836 // Note that we need to check that the closure is in the same | |
| 2837 // script as the outer function. We could have closures originating | |
| 2838 // in mixin classes whose source code is contained in a different | |
| 2839 // script. | |
| 2840 Zone* zone = Thread::Current()->zone(); | 2826 Zone* zone = Thread::Current()->zone(); |
| 2841 const Script& outer_origin = Script::Handle(zone, function.script()); | 2827 const Script& outer_origin = Script::Handle(zone, function.script()); |
| 2842 const GrowableObjectArray& closures = | 2828 const GrowableObjectArray& closures = |
| 2843 GrowableObjectArray::Handle(zone, owner.closures()); | 2829 GrowableObjectArray::Handle(zone, |
| 2830 Isolate::Current()->object_store()->closure_functions()); |
| 2844 const intptr_t num_closures = closures.Length(); | 2831 const intptr_t num_closures = closures.Length(); |
| 2845 Function& closure = Function::Handle(zone); | 2832 Function& closure = Function::Handle(zone); |
| 2846 Function& best_fit = Function::Handle(zone); | 2833 Function& best_fit = Function::Handle(zone); |
| 2847 for (intptr_t i = 0; i < num_closures; i++) { | 2834 for (intptr_t i = 0; i < num_closures; i++) { |
| 2848 closure ^= closures.At(i); | 2835 closure ^= closures.At(i); |
| 2849 if ((function.token_pos() < closure.token_pos()) && | 2836 if ((function.token_pos() < closure.token_pos()) && |
| 2850 (closure.end_token_pos() < function.end_token_pos()) && | 2837 (closure.end_token_pos() < function.end_token_pos()) && |
| 2851 (closure.token_pos() <= token_pos) && | 2838 (closure.token_pos() <= token_pos) && |
| 2852 (token_pos <= closure.end_token_pos()) && | 2839 (token_pos <= closure.end_token_pos()) && |
| 2853 (closure.script() == outer_origin.raw())) { | 2840 (closure.script() == outer_origin.raw())) { |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3260 } | 3247 } |
| 3261 | 3248 |
| 3262 | 3249 |
| 3263 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 3250 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 3264 ASSERT(bpt->next() == NULL); | 3251 ASSERT(bpt->next() == NULL); |
| 3265 bpt->set_next(code_breakpoints_); | 3252 bpt->set_next(code_breakpoints_); |
| 3266 code_breakpoints_ = bpt; | 3253 code_breakpoints_ = bpt; |
| 3267 } | 3254 } |
| 3268 | 3255 |
| 3269 } // namespace dart | 3256 } // namespace dart |
| OLD | NEW |