| 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 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 Code& code = Code::Handle(func.unoptimized_code()); | 1303 Code& code = Code::Handle(func.unoptimized_code()); |
| 1304 ASSERT(!code.IsNull()); | 1304 ASSERT(!code.IsNull()); |
| 1305 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1305 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 1306 intptr_t best_fit_index = -1; | 1306 intptr_t best_fit_index = -1; |
| 1307 intptr_t best_fit_pos = INT_MAX; | 1307 intptr_t best_fit_pos = INT_MAX; |
| 1308 uword lowest_pc = kUwordMax; | 1308 uword lowest_pc = kUwordMax; |
| 1309 intptr_t lowest_pc_index = -1; | 1309 intptr_t lowest_pc_index = -1; |
| 1310 for (intptr_t i = 0; i < desc.Length(); i++) { | 1310 for (intptr_t i = 0; i < desc.Length(); i++) { |
| 1311 intptr_t desc_token_pos = desc.TokenPos(i); | 1311 intptr_t desc_token_pos = desc.TokenPos(i); |
| 1312 ASSERT(desc_token_pos >= 0); | 1312 ASSERT(desc_token_pos >= 0); |
| 1313 if (desc_token_pos < requested_token_pos) { | |
| 1314 // This descriptor is before the first acceptable token position. | |
| 1315 continue; | |
| 1316 } | |
| 1317 if (IsSafePoint(desc, i)) { | 1313 if (IsSafePoint(desc, i)) { |
| 1314 if ((desc_token_pos < func.token_pos()) || |
| 1315 (desc_token_pos > func.end_token_pos())) { |
| 1316 // The position is outside of the function token range. This can |
| 1317 // happen in constructors, for initializer expressions that are |
| 1318 // inlined in the field declaration. |
| 1319 ASSERT(func.IsConstructor()); |
| 1320 continue; |
| 1321 } |
| 1322 if (desc_token_pos < requested_token_pos) { |
| 1323 // This descriptor is before the first acceptable token position. |
| 1324 continue; |
| 1325 } |
| 1318 if (desc_token_pos < best_fit_pos) { | 1326 if (desc_token_pos < best_fit_pos) { |
| 1319 // So far, this descriptor has the lowest token position after | 1327 // So far, this descriptor has the lowest token position after |
| 1320 // the first acceptable token position. | 1328 // the first acceptable token position. |
| 1321 best_fit_pos = desc_token_pos; | 1329 best_fit_pos = desc_token_pos; |
| 1322 best_fit_index = i; | 1330 best_fit_index = i; |
| 1323 } | 1331 } |
| 1324 if (desc.PC(i) < lowest_pc) { | 1332 if (desc.PC(i) < lowest_pc) { |
| 1325 // This descriptor so far has the lowest code address. | 1333 // This descriptor so far has the lowest code address. |
| 1326 lowest_pc = desc.PC(i); | 1334 lowest_pc = desc.PC(i); |
| 1327 lowest_pc_index = i; | 1335 lowest_pc_index = i; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1433 } | 1441 } |
| 1434 } | 1442 } |
| 1435 } | 1443 } |
| 1436 } | 1444 } |
| 1437 } | 1445 } |
| 1438 } | 1446 } |
| 1439 } | 1447 } |
| 1440 } | 1448 } |
| 1441 | 1449 |
| 1442 | 1450 |
| 1451 static bool IsDebuggableFunctionKind(const Function& func) { |
| 1452 RawFunction::Kind kind = func.kind(); |
| 1453 if ((kind == RawFunction::kImplicitGetter) || |
| 1454 (kind == RawFunction::kImplicitSetter) || |
| 1455 (kind == RawFunction::kImplicitStaticFinalGetter) || |
| 1456 (kind == RawFunction::kStaticInitializer) || |
| 1457 (kind == RawFunction::kMethodExtractor) || |
| 1458 (kind == RawFunction::kNoSuchMethodDispatcher) || |
| 1459 (kind == RawFunction::kInvokeFieldDispatcher) || |
| 1460 func.IsImplicitConstructor()) { |
| 1461 return false; |
| 1462 } |
| 1463 return true; |
| 1464 } |
| 1465 |
| 1466 |
| 1443 static void SelectBestFit(Function* best_fit, Function* func) { | 1467 static void SelectBestFit(Function* best_fit, Function* func) { |
| 1444 if (best_fit->IsNull()) { | 1468 if (best_fit->IsNull()) { |
| 1445 *best_fit = func->raw(); | 1469 *best_fit = func->raw(); |
| 1446 } else { | 1470 } else { |
| 1447 if ((func->token_pos() > best_fit->token_pos()) && | 1471 if ((func->token_pos() > best_fit->token_pos()) && |
| 1448 ((func->end_token_pos() <= best_fit->end_token_pos()))) { | 1472 ((func->end_token_pos() <= best_fit->end_token_pos()))) { |
| 1449 *best_fit = func->raw(); | 1473 *best_fit = func->raw(); |
| 1450 } | 1474 } |
| 1451 } | 1475 } |
| 1452 } | 1476 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1475 continue; | 1499 continue; |
| 1476 } | 1500 } |
| 1477 // Parse class definition if not done yet. | 1501 // Parse class definition if not done yet. |
| 1478 cls.EnsureIsFinalized(isolate_); | 1502 cls.EnsureIsFinalized(isolate_); |
| 1479 functions = cls.functions(); | 1503 functions = cls.functions(); |
| 1480 if (!functions.IsNull()) { | 1504 if (!functions.IsNull()) { |
| 1481 const intptr_t num_functions = functions.Length(); | 1505 const intptr_t num_functions = functions.Length(); |
| 1482 for (intptr_t pos = 0; pos < num_functions; pos++) { | 1506 for (intptr_t pos = 0; pos < num_functions; pos++) { |
| 1483 function ^= functions.At(pos); | 1507 function ^= functions.At(pos); |
| 1484 ASSERT(!function.IsNull()); | 1508 ASSERT(!function.IsNull()); |
| 1485 if (FunctionContains(function, script, token_pos)) { | 1509 if (IsDebuggableFunctionKind(function) && |
| 1510 FunctionContains(function, script, token_pos)) { |
| 1486 SelectBestFit(&best_fit, &function); | 1511 SelectBestFit(&best_fit, &function); |
| 1487 } | 1512 } |
| 1488 } | 1513 } |
| 1489 } | 1514 } |
| 1490 | 1515 |
| 1491 closures = cls.closures(); | 1516 closures = cls.closures(); |
| 1492 if (!closures.IsNull()) { | 1517 if (!closures.IsNull()) { |
| 1493 const intptr_t num_closures = closures.Length(); | 1518 const intptr_t num_closures = closures.Length(); |
| 1494 for (intptr_t pos = 0; pos < num_closures; pos++) { | 1519 for (intptr_t pos = 0; pos < num_closures; pos++) { |
| 1495 function ^= closures.At(pos); | 1520 function ^= closures.At(pos); |
| 1496 ASSERT(!function.IsNull()); | 1521 ASSERT(!function.IsNull()); |
| 1497 if (FunctionContains(function, script, token_pos)) { | 1522 if (IsDebuggableFunctionKind(function) && |
| 1523 FunctionContains(function, script, token_pos)) { |
| 1498 SelectBestFit(&best_fit, &function); | 1524 SelectBestFit(&best_fit, &function); |
| 1499 } | 1525 } |
| 1500 } | 1526 } |
| 1501 } | 1527 } |
| 1502 } | 1528 } |
| 1503 } | 1529 } |
| 1504 return best_fit.raw(); | 1530 return best_fit.raw(); |
| 1505 } | 1531 } |
| 1506 | 1532 |
| 1507 | 1533 |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1884 obj_cache_ = new RemoteObjectCache(64); | 1910 obj_cache_ = new RemoteObjectCache(64); |
| 1885 | 1911 |
| 1886 (*event_handler_)(event); | 1912 (*event_handler_)(event); |
| 1887 | 1913 |
| 1888 pause_event_ = NULL; | 1914 pause_event_ = NULL; |
| 1889 obj_cache_ = NULL; // Zone allocated | 1915 obj_cache_ = NULL; // Zone allocated |
| 1890 } | 1916 } |
| 1891 | 1917 |
| 1892 | 1918 |
| 1893 bool Debugger::IsDebuggable(const Function& func) { | 1919 bool Debugger::IsDebuggable(const Function& func) { |
| 1894 RawFunction::Kind fkind = func.kind(); | 1920 if (!IsDebuggableFunctionKind(func)) { |
| 1895 if ((fkind == RawFunction::kImplicitGetter) || | |
| 1896 (fkind == RawFunction::kImplicitSetter) || | |
| 1897 (fkind == RawFunction::kImplicitStaticFinalGetter) || | |
| 1898 (fkind == RawFunction::kStaticInitializer) || | |
| 1899 (fkind == RawFunction::kMethodExtractor) || | |
| 1900 (fkind == RawFunction::kNoSuchMethodDispatcher) || | |
| 1901 (fkind == RawFunction::kInvokeFieldDispatcher)) { | |
| 1902 return false; | 1921 return false; |
| 1903 } | 1922 } |
| 1904 const Class& cls = Class::Handle(func.Owner()); | 1923 const Class& cls = Class::Handle(func.Owner()); |
| 1905 const Library& lib = Library::Handle(cls.library()); | 1924 const Library& lib = Library::Handle(cls.library()); |
| 1906 return lib.IsDebuggable(); | 1925 return lib.IsDebuggable(); |
| 1907 } | 1926 } |
| 1908 | 1927 |
| 1909 | 1928 |
| 1910 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, | 1929 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, |
| 1911 SourceBreakpoint* bpt) { | 1930 SourceBreakpoint* bpt) { |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2286 } | 2305 } |
| 2287 | 2306 |
| 2288 | 2307 |
| 2289 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2308 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2290 ASSERT(bpt->next() == NULL); | 2309 ASSERT(bpt->next() == NULL); |
| 2291 bpt->set_next(code_breakpoints_); | 2310 bpt->set_next(code_breakpoints_); |
| 2292 code_breakpoints_ = bpt; | 2311 code_breakpoints_ = bpt; |
| 2293 } | 2312 } |
| 2294 | 2313 |
| 2295 } // namespace dart | 2314 } // namespace dart |
| OLD | NEW |