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 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 | 1163 |
1164 | 1164 |
1165 // Return the debug info for this function. EnsureDebugInfo must be called | 1165 // Return the debug info for this function. EnsureDebugInfo must be called |
1166 // prior to ensure the debug info has been generated for shared. | 1166 // prior to ensure the debug info has been generated for shared. |
1167 Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) { | 1167 Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) { |
1168 ASSERT(HasDebugInfo(shared)); | 1168 ASSERT(HasDebugInfo(shared)); |
1169 return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); | 1169 return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); |
1170 } | 1170 } |
1171 | 1171 |
1172 | 1172 |
1173 void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared, | 1173 void Debug::SetBreakPoint(Handle<JSFunction> function, |
1174 Handle<Object> break_point_object, | 1174 Handle<Object> break_point_object, |
1175 int* source_position) { | 1175 int* source_position) { |
1176 HandleScope scope(isolate_); | 1176 HandleScope scope(isolate_); |
1177 | 1177 |
1178 PrepareForBreakPoints(); | 1178 PrepareForBreakPoints(); |
1179 | 1179 |
1180 if (!EnsureDebugInfo(shared)) { | 1180 // Make sure the function is compiled and has set up the debug info. |
| 1181 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1182 if (!EnsureDebugInfo(shared, function)) { |
1181 // Return if retrieving debug info failed. | 1183 // Return if retrieving debug info failed. |
1182 return; | 1184 return; |
1183 } | 1185 } |
1184 | 1186 |
1185 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1187 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1186 // Source positions starts with zero. | 1188 // Source positions starts with zero. |
1187 ASSERT(*source_position >= 0); | 1189 ASSERT(*source_position >= 0); |
1188 | 1190 |
1189 // Find the break point and change it. | 1191 // Find the break point and change it. |
1190 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); | 1192 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); |
1191 it.FindBreakLocationFromPosition(*source_position); | 1193 it.FindBreakLocationFromPosition(*source_position); |
1192 it.SetBreakPoint(break_point_object); | 1194 it.SetBreakPoint(break_point_object); |
1193 | 1195 |
1194 *source_position = it.position(); | 1196 *source_position = it.position(); |
1195 | 1197 |
1196 // At least one active break point now. | 1198 // At least one active break point now. |
1197 ASSERT(debug_info->GetBreakPointCount() > 0); | 1199 ASSERT(debug_info->GetBreakPointCount() > 0); |
1198 } | 1200 } |
1199 | 1201 |
1200 | 1202 |
| 1203 bool Debug::SetBreakPointForScript(Handle<Script> script, |
| 1204 Handle<Object> break_point_object, |
| 1205 int* source_position) { |
| 1206 HandleScope scope(isolate_); |
| 1207 |
| 1208 // No need to call PrepareForBreakPoints because it will be called |
| 1209 // implicitly by Runtime::FindSharedFunctionInfoInScript. |
| 1210 Object* result = Runtime::FindSharedFunctionInfoInScript(isolate_, |
| 1211 script, |
| 1212 *source_position); |
| 1213 if (result->IsUndefined()) return false; |
| 1214 |
| 1215 // Make sure the function has set up the debug info. |
| 1216 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); |
| 1217 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { |
| 1218 // Return if retrieving debug info failed. |
| 1219 return false; |
| 1220 } |
| 1221 |
| 1222 // Find position within function. The script position might be before the |
| 1223 // source position of the first function. |
| 1224 int position; |
| 1225 if (shared->start_position() > *source_position) { |
| 1226 position = 0; |
| 1227 } else { |
| 1228 position = *source_position - shared->start_position(); |
| 1229 } |
| 1230 |
| 1231 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| 1232 // Source positions starts with zero. |
| 1233 ASSERT(position >= 0); |
| 1234 |
| 1235 // Find the break point and change it. |
| 1236 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); |
| 1237 it.FindBreakLocationFromPosition(position); |
| 1238 it.SetBreakPoint(break_point_object); |
| 1239 |
| 1240 *source_position = it.position() + shared->start_position(); |
| 1241 |
| 1242 // At least one active break point now. |
| 1243 ASSERT(debug_info->GetBreakPointCount() > 0); |
| 1244 return true; |
| 1245 } |
| 1246 |
| 1247 |
1201 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { | 1248 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { |
1202 HandleScope scope(isolate_); | 1249 HandleScope scope(isolate_); |
1203 | 1250 |
1204 DebugInfoListNode* node = debug_info_list_; | 1251 DebugInfoListNode* node = debug_info_list_; |
1205 while (node != NULL) { | 1252 while (node != NULL) { |
1206 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), | 1253 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), |
1207 break_point_object); | 1254 break_point_object); |
1208 if (!result->IsUndefined()) { | 1255 if (!result->IsUndefined()) { |
1209 // Get information in the break point. | 1256 // Get information in the break point. |
1210 BreakPointInfo* break_point_info = BreakPointInfo::cast(result); | 1257 BreakPointInfo* break_point_info = BreakPointInfo::cast(result); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1242 node = node->next(); | 1289 node = node->next(); |
1243 } | 1290 } |
1244 | 1291 |
1245 // Remove all debug info. | 1292 // Remove all debug info. |
1246 while (debug_info_list_ != NULL) { | 1293 while (debug_info_list_ != NULL) { |
1247 RemoveDebugInfo(debug_info_list_->debug_info()); | 1294 RemoveDebugInfo(debug_info_list_->debug_info()); |
1248 } | 1295 } |
1249 } | 1296 } |
1250 | 1297 |
1251 | 1298 |
1252 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { | 1299 void Debug::FloodWithOneShot(Handle<JSFunction> function) { |
1253 PrepareForBreakPoints(); | 1300 PrepareForBreakPoints(); |
1254 // Make sure the function has set up the debug info. | 1301 |
1255 if (!EnsureDebugInfo(shared)) { | 1302 // Make sure the function is compiled and has set up the debug info. |
| 1303 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1304 if (!EnsureDebugInfo(shared, function)) { |
1256 // Return if we failed to retrieve the debug info. | 1305 // Return if we failed to retrieve the debug info. |
1257 return; | 1306 return; |
1258 } | 1307 } |
1259 | 1308 |
1260 // Flood the function with break points. | 1309 // Flood the function with break points. |
1261 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); | 1310 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); |
1262 while (!it.Done()) { | 1311 while (!it.Done()) { |
1263 it.SetOneShot(); | 1312 it.SetOneShot(); |
1264 it.Next(); | 1313 it.Next(); |
1265 } | 1314 } |
1266 } | 1315 } |
1267 | 1316 |
1268 | 1317 |
1269 void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) { | 1318 void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) { |
1270 Handle<FixedArray> new_bindings(function->function_bindings()); | 1319 Handle<FixedArray> new_bindings(function->function_bindings()); |
1271 Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex)); | 1320 Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex)); |
1272 | 1321 |
1273 if (!bindee.is_null() && bindee->IsJSFunction() && | 1322 if (!bindee.is_null() && bindee->IsJSFunction() && |
1274 !JSFunction::cast(*bindee)->IsBuiltin()) { | 1323 !JSFunction::cast(*bindee)->IsBuiltin()) { |
1275 Handle<SharedFunctionInfo> shared_info(JSFunction::cast(*bindee)->shared()); | 1324 Handle<JSFunction> bindee_function(JSFunction::cast(*bindee)); |
1276 Debug::FloodWithOneShot(shared_info); | 1325 Debug::FloodWithOneShot(bindee_function); |
1277 } | 1326 } |
1278 } | 1327 } |
1279 | 1328 |
1280 | 1329 |
1281 void Debug::FloodHandlerWithOneShot() { | 1330 void Debug::FloodHandlerWithOneShot() { |
1282 // Iterate through the JavaScript stack looking for handlers. | 1331 // Iterate through the JavaScript stack looking for handlers. |
1283 StackFrame::Id id = break_frame_id(); | 1332 StackFrame::Id id = break_frame_id(); |
1284 if (id == StackFrame::NO_ID) { | 1333 if (id == StackFrame::NO_ID) { |
1285 // If there is no JavaScript stack don't do anything. | 1334 // If there is no JavaScript stack don't do anything. |
1286 return; | 1335 return; |
1287 } | 1336 } |
1288 for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) { | 1337 for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) { |
1289 JavaScriptFrame* frame = it.frame(); | 1338 JavaScriptFrame* frame = it.frame(); |
1290 if (frame->HasHandler()) { | 1339 if (frame->HasHandler()) { |
1291 Handle<SharedFunctionInfo> shared = | |
1292 Handle<SharedFunctionInfo>( | |
1293 JSFunction::cast(frame->function())->shared()); | |
1294 // Flood the function with the catch block with break points | 1340 // Flood the function with the catch block with break points |
1295 FloodWithOneShot(shared); | 1341 JSFunction* function = JSFunction::cast(frame->function()); |
| 1342 FloodWithOneShot(Handle<JSFunction>(function)); |
1296 return; | 1343 return; |
1297 } | 1344 } |
1298 } | 1345 } |
1299 } | 1346 } |
1300 | 1347 |
1301 | 1348 |
1302 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { | 1349 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { |
1303 if (type == BreakUncaughtException) { | 1350 if (type == BreakUncaughtException) { |
1304 break_on_uncaught_exception_ = enable; | 1351 break_on_uncaught_exception_ = enable; |
1305 } else { | 1352 } else { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 | 1399 |
1353 // If the function on the top frame is unresolved perform step out. This will | 1400 // If the function on the top frame is unresolved perform step out. This will |
1354 // be the case when calling unknown functions and having the debugger stopped | 1401 // be the case when calling unknown functions and having the debugger stopped |
1355 // in an unhandled exception. | 1402 // in an unhandled exception. |
1356 if (!frame->function()->IsJSFunction()) { | 1403 if (!frame->function()->IsJSFunction()) { |
1357 // Step out: Find the calling JavaScript frame and flood it with | 1404 // Step out: Find the calling JavaScript frame and flood it with |
1358 // breakpoints. | 1405 // breakpoints. |
1359 frames_it.Advance(); | 1406 frames_it.Advance(); |
1360 // Fill the function to return to with one-shot break points. | 1407 // Fill the function to return to with one-shot break points. |
1361 JSFunction* function = JSFunction::cast(frames_it.frame()->function()); | 1408 JSFunction* function = JSFunction::cast(frames_it.frame()->function()); |
1362 FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); | 1409 FloodWithOneShot(Handle<JSFunction>(function)); |
1363 return; | 1410 return; |
1364 } | 1411 } |
1365 | 1412 |
1366 // Get the debug info (create it if it does not exist). | 1413 // Get the debug info (create it if it does not exist). |
1367 Handle<SharedFunctionInfo> shared = | 1414 Handle<JSFunction> function(JSFunction::cast(frame->function())); |
1368 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 1415 Handle<SharedFunctionInfo> shared(function->shared()); |
1369 if (!EnsureDebugInfo(shared)) { | 1416 if (!EnsureDebugInfo(shared, function)) { |
1370 // Return if ensuring debug info failed. | 1417 // Return if ensuring debug info failed. |
1371 return; | 1418 return; |
1372 } | 1419 } |
1373 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1420 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1374 | 1421 |
1375 // Find the break location where execution has stopped. | 1422 // Find the break location where execution has stopped. |
1376 BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS); | 1423 BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS); |
1377 it.FindBreakLocationFromAddress(frame->pc()); | 1424 it.FindBreakLocationFromAddress(frame->pc()); |
1378 | 1425 |
1379 // Compute whether or not the target is a call target. | 1426 // Compute whether or not the target is a call target. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1429 // Skip builtin functions on the stack. | 1476 // Skip builtin functions on the stack. |
1430 while (!frames_it.done() && | 1477 while (!frames_it.done() && |
1431 JSFunction::cast(frames_it.frame()->function())->IsBuiltin()) { | 1478 JSFunction::cast(frames_it.frame()->function())->IsBuiltin()) { |
1432 frames_it.Advance(); | 1479 frames_it.Advance(); |
1433 } | 1480 } |
1434 // Step out: If there is a JavaScript caller frame, we need to | 1481 // Step out: If there is a JavaScript caller frame, we need to |
1435 // flood it with breakpoints. | 1482 // flood it with breakpoints. |
1436 if (!frames_it.done()) { | 1483 if (!frames_it.done()) { |
1437 // Fill the function to return to with one-shot break points. | 1484 // Fill the function to return to with one-shot break points. |
1438 JSFunction* function = JSFunction::cast(frames_it.frame()->function()); | 1485 JSFunction* function = JSFunction::cast(frames_it.frame()->function()); |
1439 FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); | 1486 FloodWithOneShot(Handle<JSFunction>(function)); |
1440 // Set target frame pointer. | 1487 // Set target frame pointer. |
1441 ActivateStepOut(frames_it.frame()); | 1488 ActivateStepOut(frames_it.frame()); |
1442 } | 1489 } |
1443 } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) || | 1490 } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) || |
1444 !call_function_stub.is_null() || is_at_restarted_function) | 1491 !call_function_stub.is_null() || is_at_restarted_function) |
1445 || step_action == StepNext || step_action == StepMin) { | 1492 || step_action == StepNext || step_action == StepMin) { |
1446 // Step next or step min. | 1493 // Step next or step min. |
1447 | 1494 |
1448 // Fill the current function with one-shot break points. | 1495 // Fill the current function with one-shot break points. |
1449 FloodWithOneShot(shared); | 1496 FloodWithOneShot(function); |
1450 | 1497 |
1451 // Remember source position and frame to handle step next. | 1498 // Remember source position and frame to handle step next. |
1452 thread_local_.last_statement_position_ = | 1499 thread_local_.last_statement_position_ = |
1453 debug_info->code()->SourceStatementPosition(frame->pc()); | 1500 debug_info->code()->SourceStatementPosition(frame->pc()); |
1454 thread_local_.last_fp_ = frame->UnpaddedFP(); | 1501 thread_local_.last_fp_ = frame->UnpaddedFP(); |
1455 } else { | 1502 } else { |
1456 // If there's restarter frame on top of the stack, just get the pointer | 1503 // If there's restarter frame on top of the stack, just get the pointer |
1457 // to function which is going to be restarted. | 1504 // to function which is going to be restarted. |
1458 if (is_at_restarted_function) { | 1505 if (is_at_restarted_function) { |
1459 Handle<JSFunction> restarted_function( | 1506 Handle<JSFunction> restarted_function( |
1460 JSFunction::cast(*thread_local_.restarter_frame_function_pointer_)); | 1507 JSFunction::cast(*thread_local_.restarter_frame_function_pointer_)); |
1461 Handle<SharedFunctionInfo> restarted_shared( | 1508 FloodWithOneShot(restarted_function); |
1462 restarted_function->shared()); | |
1463 FloodWithOneShot(restarted_shared); | |
1464 } else if (!call_function_stub.is_null()) { | 1509 } else if (!call_function_stub.is_null()) { |
1465 // If it's CallFunction stub ensure target function is compiled and flood | 1510 // If it's CallFunction stub ensure target function is compiled and flood |
1466 // it with one shot breakpoints. | 1511 // it with one shot breakpoints. |
1467 | 1512 |
1468 // Find out number of arguments from the stub minor key. | 1513 // Find out number of arguments from the stub minor key. |
1469 // Reverse lookup required as the minor key cannot be retrieved | 1514 // Reverse lookup required as the minor key cannot be retrieved |
1470 // from the code object. | 1515 // from the code object. |
1471 Handle<Object> obj( | 1516 Handle<Object> obj( |
1472 isolate_->heap()->code_stubs()->SlowReverseLookup( | 1517 isolate_->heap()->code_stubs()->SlowReverseLookup( |
1473 *call_function_stub)); | 1518 *call_function_stub)); |
(...skipping 21 matching lines...) Expand all Loading... |
1495 ASSERT(expressions_count - 2 - call_function_arg_count >= 0); | 1540 ASSERT(expressions_count - 2 - call_function_arg_count >= 0); |
1496 Object* fun = frame->GetExpression( | 1541 Object* fun = frame->GetExpression( |
1497 expressions_count - 2 - call_function_arg_count); | 1542 expressions_count - 2 - call_function_arg_count); |
1498 if (fun->IsJSFunction()) { | 1543 if (fun->IsJSFunction()) { |
1499 Handle<JSFunction> js_function(JSFunction::cast(fun)); | 1544 Handle<JSFunction> js_function(JSFunction::cast(fun)); |
1500 if (js_function->shared()->bound()) { | 1545 if (js_function->shared()->bound()) { |
1501 Debug::FloodBoundFunctionWithOneShot(js_function); | 1546 Debug::FloodBoundFunctionWithOneShot(js_function); |
1502 } else if (!js_function->IsBuiltin()) { | 1547 } else if (!js_function->IsBuiltin()) { |
1503 // Don't step into builtins. | 1548 // Don't step into builtins. |
1504 // It will also compile target function if it's not compiled yet. | 1549 // It will also compile target function if it's not compiled yet. |
1505 FloodWithOneShot(Handle<SharedFunctionInfo>(js_function->shared())); | 1550 FloodWithOneShot(js_function); |
1506 } | 1551 } |
1507 } | 1552 } |
1508 } | 1553 } |
1509 | 1554 |
1510 // Fill the current function with one-shot break points even for step in on | 1555 // Fill the current function with one-shot break points even for step in on |
1511 // a call target as the function called might be a native function for | 1556 // a call target as the function called might be a native function for |
1512 // which step in will not stop. It also prepares for stepping in | 1557 // which step in will not stop. It also prepares for stepping in |
1513 // getters/setters. | 1558 // getters/setters. |
1514 FloodWithOneShot(shared); | 1559 FloodWithOneShot(function); |
1515 | 1560 |
1516 if (is_load_or_store) { | 1561 if (is_load_or_store) { |
1517 // Remember source position and frame to handle step in getter/setter. If | 1562 // Remember source position and frame to handle step in getter/setter. If |
1518 // there is a custom getter/setter it will be handled in | 1563 // there is a custom getter/setter it will be handled in |
1519 // Object::Get/SetPropertyWithCallback, otherwise the step action will be | 1564 // Object::Get/SetPropertyWithCallback, otherwise the step action will be |
1520 // propagated on the next Debug::Break. | 1565 // propagated on the next Debug::Break. |
1521 thread_local_.last_statement_position_ = | 1566 thread_local_.last_statement_position_ = |
1522 debug_info->code()->SourceStatementPosition(frame->pc()); | 1567 debug_info->code()->SourceStatementPosition(frame->pc()); |
1523 thread_local_.last_fp_ = frame->UnpaddedFP(); | 1568 thread_local_.last_fp_ = frame->UnpaddedFP(); |
1524 } | 1569 } |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1704 if (function->shared()->code() == | 1749 if (function->shared()->code() == |
1705 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply) || | 1750 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply) || |
1706 function->shared()->code() == | 1751 function->shared()->code() == |
1707 Isolate::Current()->builtins()->builtin(Builtins::kFunctionCall)) { | 1752 Isolate::Current()->builtins()->builtin(Builtins::kFunctionCall)) { |
1708 // Handle function.apply and function.call separately to flood the | 1753 // Handle function.apply and function.call separately to flood the |
1709 // function to be called and not the code for Builtins::FunctionApply or | 1754 // function to be called and not the code for Builtins::FunctionApply or |
1710 // Builtins::FunctionCall. The receiver of call/apply is the target | 1755 // Builtins::FunctionCall. The receiver of call/apply is the target |
1711 // function. | 1756 // function. |
1712 if (!holder.is_null() && holder->IsJSFunction() && | 1757 if (!holder.is_null() && holder->IsJSFunction() && |
1713 !JSFunction::cast(*holder)->IsBuiltin()) { | 1758 !JSFunction::cast(*holder)->IsBuiltin()) { |
1714 Handle<SharedFunctionInfo> shared_info( | 1759 Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder); |
1715 JSFunction::cast(*holder)->shared()); | 1760 Debug::FloodWithOneShot(js_function); |
1716 Debug::FloodWithOneShot(shared_info); | |
1717 } | 1761 } |
1718 } else { | 1762 } else { |
1719 Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); | 1763 Debug::FloodWithOneShot(function); |
1720 } | 1764 } |
1721 } | 1765 } |
1722 } | 1766 } |
1723 } | 1767 } |
1724 | 1768 |
1725 | 1769 |
1726 void Debug::ClearStepping() { | 1770 void Debug::ClearStepping() { |
1727 // Clear the various stepping setup. | 1771 // Clear the various stepping setup. |
1728 ClearOneShot(); | 1772 ClearOneShot(); |
1729 ClearStepIn(); | 1773 ClearStepIn(); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1949 | 1993 |
1950 void Debug::PrepareForBreakPoints() { | 1994 void Debug::PrepareForBreakPoints() { |
1951 // If preparing for the first break point make sure to deoptimize all | 1995 // If preparing for the first break point make sure to deoptimize all |
1952 // functions as debugging does not work with optimized code. | 1996 // functions as debugging does not work with optimized code. |
1953 if (!has_break_points_) { | 1997 if (!has_break_points_) { |
1954 Deoptimizer::DeoptimizeAll(); | 1998 Deoptimizer::DeoptimizeAll(); |
1955 | 1999 |
1956 Handle<Code> lazy_compile = | 2000 Handle<Code> lazy_compile = |
1957 Handle<Code>(isolate_->builtins()->builtin(Builtins::kLazyCompile)); | 2001 Handle<Code>(isolate_->builtins()->builtin(Builtins::kLazyCompile)); |
1958 | 2002 |
| 2003 // There will be at least one break point when we are done. |
| 2004 has_break_points_ = true; |
| 2005 |
1959 // Keep the list of activated functions in a handlified list as it | 2006 // Keep the list of activated functions in a handlified list as it |
1960 // is used both in GC and non-GC code. | 2007 // is used both in GC and non-GC code. |
1961 List<Handle<JSFunction> > active_functions(100); | 2008 List<Handle<JSFunction> > active_functions(100); |
1962 | 2009 |
1963 { | 2010 { |
1964 // We are going to iterate heap to find all functions without | 2011 // We are going to iterate heap to find all functions without |
1965 // debug break slots. | 2012 // debug break slots. |
1966 isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 2013 isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
1967 "preparing for breakpoints"); | 2014 "preparing for breakpoints"); |
1968 | 2015 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2056 isolate_->thread_local_top()); | 2103 isolate_->thread_local_top()); |
2057 | 2104 |
2058 ActiveFunctionsRedirector active_functions_redirector; | 2105 ActiveFunctionsRedirector active_functions_redirector; |
2059 isolate_->thread_manager()->IterateArchivedThreads( | 2106 isolate_->thread_manager()->IterateArchivedThreads( |
2060 &active_functions_redirector); | 2107 &active_functions_redirector); |
2061 } | 2108 } |
2062 } | 2109 } |
2063 | 2110 |
2064 | 2111 |
2065 // Ensures the debug information is present for shared. | 2112 // Ensures the debug information is present for shared. |
2066 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { | 2113 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, |
| 2114 Handle<JSFunction> function) { |
2067 // Return if we already have the debug info for shared. | 2115 // Return if we already have the debug info for shared. |
2068 if (HasDebugInfo(shared)) { | 2116 if (HasDebugInfo(shared)) { |
2069 ASSERT(shared->is_compiled()); | 2117 ASSERT(shared->is_compiled()); |
2070 return true; | 2118 return true; |
2071 } | 2119 } |
2072 | 2120 |
2073 // Ensure shared in compiled. Return false if this failed. | 2121 // Make sure we are prepared to handle breakpoints. |
2074 if (!SharedFunctionInfo::EnsureCompiled(shared, CLEAR_EXCEPTION)) { | 2122 ASSERT(has_break_points_); |
| 2123 |
| 2124 // Ensure function is compiled. Return false if this failed. |
| 2125 if (!function.is_null() && |
| 2126 !JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION)) { |
2075 return false; | 2127 return false; |
2076 } | 2128 } |
2077 | 2129 |
2078 // Create the debug info object. | 2130 // Create the debug info object. |
2079 Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared); | 2131 Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared); |
2080 | 2132 |
2081 // Add debug info to the list. | 2133 // Add debug info to the list. |
2082 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); | 2134 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); |
2083 node->set_next(debug_info_list_); | 2135 node->set_next(debug_info_list_); |
2084 debug_info_list_ = node; | 2136 debug_info_list_ = node; |
2085 | 2137 |
2086 // Now there is at least one break point. | |
2087 has_break_points_ = true; | |
2088 | |
2089 return true; | 2138 return true; |
2090 } | 2139 } |
2091 | 2140 |
2092 | 2141 |
2093 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { | 2142 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { |
2094 ASSERT(debug_info_list_ != NULL); | 2143 ASSERT(debug_info_list_ != NULL); |
2095 // Run through the debug info objects to find this one and remove it. | 2144 // Run through the debug info objects to find this one and remove it. |
2096 DebugInfoListNode* prev = NULL; | 2145 DebugInfoListNode* prev = NULL; |
2097 DebugInfoListNode* current = debug_info_list_; | 2146 DebugInfoListNode* current = debug_info_list_; |
2098 while (current != NULL) { | 2147 while (current != NULL) { |
(...skipping 21 matching lines...) Expand all Loading... |
2120 UNREACHABLE(); | 2169 UNREACHABLE(); |
2121 } | 2170 } |
2122 | 2171 |
2123 | 2172 |
2124 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { | 2173 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { |
2125 HandleScope scope(isolate_); | 2174 HandleScope scope(isolate_); |
2126 | 2175 |
2127 PrepareForBreakPoints(); | 2176 PrepareForBreakPoints(); |
2128 | 2177 |
2129 // Get the executing function in which the debug break occurred. | 2178 // Get the executing function in which the debug break occurred. |
2130 Handle<SharedFunctionInfo> shared = | 2179 Handle<JSFunction> function(JSFunction::cast(frame->function())); |
2131 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 2180 Handle<SharedFunctionInfo> shared(function->shared()); |
2132 if (!EnsureDebugInfo(shared)) { | 2181 if (!EnsureDebugInfo(shared, function)) { |
2133 // Return if we failed to retrieve the debug info. | 2182 // Return if we failed to retrieve the debug info. |
2134 return; | 2183 return; |
2135 } | 2184 } |
2136 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 2185 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
2137 Handle<Code> code(debug_info->code()); | 2186 Handle<Code> code(debug_info->code()); |
2138 Handle<Code> original_code(debug_info->original_code()); | 2187 Handle<Code> original_code(debug_info->original_code()); |
2139 #ifdef DEBUG | 2188 #ifdef DEBUG |
2140 // Get the code which is actually executing. | 2189 // Get the code which is actually executing. |
2141 Handle<Code> frame_code(frame->LookupCode()); | 2190 Handle<Code> frame_code(frame->LookupCode()); |
2142 ASSERT(frame_code.is_identical_to(code)); | 2191 ASSERT(frame_code.is_identical_to(code)); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2212 // If there are no break points this cannot be break at return, as | 2261 // If there are no break points this cannot be break at return, as |
2213 // the debugger statement and stack guard bebug break cannot be at | 2262 // the debugger statement and stack guard bebug break cannot be at |
2214 // return. | 2263 // return. |
2215 if (!has_break_points_) { | 2264 if (!has_break_points_) { |
2216 return false; | 2265 return false; |
2217 } | 2266 } |
2218 | 2267 |
2219 PrepareForBreakPoints(); | 2268 PrepareForBreakPoints(); |
2220 | 2269 |
2221 // Get the executing function in which the debug break occurred. | 2270 // Get the executing function in which the debug break occurred. |
2222 Handle<SharedFunctionInfo> shared = | 2271 Handle<JSFunction> function(JSFunction::cast(frame->function())); |
2223 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 2272 Handle<SharedFunctionInfo> shared(function->shared()); |
2224 if (!EnsureDebugInfo(shared)) { | 2273 if (!EnsureDebugInfo(shared, function)) { |
2225 // Return if we failed to retrieve the debug info. | 2274 // Return if we failed to retrieve the debug info. |
2226 return false; | 2275 return false; |
2227 } | 2276 } |
2228 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 2277 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
2229 Handle<Code> code(debug_info->code()); | 2278 Handle<Code> code(debug_info->code()); |
2230 #ifdef DEBUG | 2279 #ifdef DEBUG |
2231 // Get the code which is actually executing. | 2280 // Get the code which is actually executing. |
2232 Handle<Code> frame_code(frame->LookupCode()); | 2281 Handle<Code> frame_code(frame->LookupCode()); |
2233 ASSERT(frame_code.is_identical_to(code)); | 2282 ASSERT(frame_code.is_identical_to(code)); |
2234 #endif | 2283 #endif |
(...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3621 { | 3670 { |
3622 Locker locker; | 3671 Locker locker; |
3623 Isolate::Current()->debugger()->CallMessageDispatchHandler(); | 3672 Isolate::Current()->debugger()->CallMessageDispatchHandler(); |
3624 } | 3673 } |
3625 } | 3674 } |
3626 } | 3675 } |
3627 | 3676 |
3628 #endif // ENABLE_DEBUGGER_SUPPORT | 3677 #endif // ENABLE_DEBUGGER_SUPPORT |
3629 | 3678 |
3630 } } // namespace v8::internal | 3679 } } // namespace v8::internal |
OLD | NEW |