OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 it.SkipToPosition(position_, BREAK_POSITION_ALIGNED); | 118 it.SkipToPosition(position_, BREAK_POSITION_ALIGNED); |
119 return it.code_offset() == code_offset_; | 119 return it.code_offset() == code_offset_; |
120 } else { | 120 } else { |
121 DCHECK(abstract_code_->IsBytecodeArray()); | 121 DCHECK(abstract_code_->IsBytecodeArray()); |
122 BytecodeArrayBreakIterator it(debug_info); | 122 BytecodeArrayBreakIterator it(debug_info); |
123 it.SkipToPosition(position_, BREAK_POSITION_ALIGNED); | 123 it.SkipToPosition(position_, BREAK_POSITION_ALIGNED); |
124 return it.code_offset() == code_offset_; | 124 return it.code_offset() == code_offset_; |
125 } | 125 } |
126 } | 126 } |
127 | 127 |
| 128 debug::BreakLocationType BreakLocation::type() const { |
| 129 switch (type_) { |
| 130 case DEBUGGER_STATEMENT: |
| 131 return debug::kDebuggerStatementBreakLocation; |
| 132 case DEBUG_BREAK_SLOT_AT_CALL: |
| 133 return debug::kCallBreakLocation; |
| 134 case DEBUG_BREAK_SLOT_AT_RETURN: |
| 135 return debug::kReturnBreakLocation; |
| 136 default: |
| 137 return debug::kCommonBreakLocation; |
| 138 } |
| 139 return debug::kCommonBreakLocation; |
| 140 } |
| 141 |
128 std::unique_ptr<BreakIterator> BreakIterator::GetIterator( | 142 std::unique_ptr<BreakIterator> BreakIterator::GetIterator( |
129 Handle<DebugInfo> debug_info, Handle<AbstractCode> abstract_code) { | 143 Handle<DebugInfo> debug_info, Handle<AbstractCode> abstract_code) { |
130 if (abstract_code->IsBytecodeArray()) { | 144 if (abstract_code->IsBytecodeArray()) { |
131 DCHECK(debug_info->HasDebugBytecodeArray()); | 145 DCHECK(debug_info->HasDebugBytecodeArray()); |
132 return std::unique_ptr<BreakIterator>( | 146 return std::unique_ptr<BreakIterator>( |
133 new BytecodeArrayBreakIterator(debug_info)); | 147 new BytecodeArrayBreakIterator(debug_info)); |
134 } else { | 148 } else { |
135 DCHECK(abstract_code->IsCode()); | 149 DCHECK(abstract_code->IsCode()); |
136 DCHECK(debug_info->HasDebugCode()); | 150 DCHECK(debug_info->HasDebugCode()); |
137 return std::unique_ptr<BreakIterator>(new CodeBreakIterator(debug_info)); | 151 return std::unique_ptr<BreakIterator>(new CodeBreakIterator(debug_info)); |
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 RedirectActiveFunctions redirect_visitor(*shared); | 1322 RedirectActiveFunctions redirect_visitor(*shared); |
1309 redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top()); | 1323 redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top()); |
1310 isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor); | 1324 isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor); |
1311 | 1325 |
1312 return true; | 1326 return true; |
1313 } | 1327 } |
1314 | 1328 |
1315 namespace { | 1329 namespace { |
1316 template <typename Iterator> | 1330 template <typename Iterator> |
1317 void GetBreakablePositions(Iterator* it, int start_position, int end_position, | 1331 void GetBreakablePositions(Iterator* it, int start_position, int end_position, |
1318 BreakPositionAlignment alignment, | 1332 std::vector<BreakLocation>* locations) { |
1319 std::set<int>* positions) { | 1333 it->SkipToPosition(start_position, BREAK_POSITION_ALIGNED); |
1320 it->SkipToPosition(start_position, alignment); | |
1321 while (!it->Done() && it->position() < end_position && | 1334 while (!it->Done() && it->position() < end_position && |
1322 it->position() >= start_position) { | 1335 it->position() >= start_position) { |
1323 positions->insert(alignment == STATEMENT_ALIGNED ? it->statement_position() | 1336 locations->push_back(it->GetBreakLocation()); |
1324 : it->position()); | |
1325 it->Next(); | 1337 it->Next(); |
1326 } | 1338 } |
1327 } | 1339 } |
1328 | 1340 |
1329 void FindBreakablePositions(Handle<DebugInfo> debug_info, int start_position, | 1341 void FindBreakablePositions(Handle<DebugInfo> debug_info, int start_position, |
1330 int end_position, BreakPositionAlignment alignment, | 1342 int end_position, |
1331 std::set<int>* positions) { | 1343 std::vector<BreakLocation>* locations) { |
1332 if (debug_info->HasDebugCode()) { | 1344 if (debug_info->HasDebugCode()) { |
1333 CodeBreakIterator it(debug_info); | 1345 CodeBreakIterator it(debug_info); |
1334 GetBreakablePositions(&it, start_position, end_position, alignment, | 1346 GetBreakablePositions(&it, start_position, end_position, locations); |
1335 positions); | |
1336 } else { | 1347 } else { |
1337 DCHECK(debug_info->HasDebugBytecodeArray()); | 1348 DCHECK(debug_info->HasDebugBytecodeArray()); |
1338 BytecodeArrayBreakIterator it(debug_info); | 1349 BytecodeArrayBreakIterator it(debug_info); |
1339 GetBreakablePositions(&it, start_position, end_position, alignment, | 1350 GetBreakablePositions(&it, start_position, end_position, locations); |
1340 positions); | |
1341 } | 1351 } |
1342 } | 1352 } |
1343 } // namespace | 1353 } // namespace |
1344 | 1354 |
1345 bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position, | 1355 bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position, |
1346 int end_position, bool restrict_to_function, | 1356 int end_position, bool restrict_to_function, |
1347 std::set<int>* positions) { | 1357 std::vector<BreakLocation>* locations) { |
1348 if (restrict_to_function) { | 1358 if (restrict_to_function) { |
1349 Handle<Object> result = | 1359 Handle<Object> result = |
1350 FindSharedFunctionInfoInScript(script, start_position); | 1360 FindSharedFunctionInfoInScript(script, start_position); |
1351 if (result->IsUndefined(isolate_)) return false; | 1361 if (result->IsUndefined(isolate_)) return false; |
1352 | 1362 |
1353 // Make sure the function has set up the debug info. | 1363 // Make sure the function has set up the debug info. |
1354 Handle<SharedFunctionInfo> shared = | 1364 Handle<SharedFunctionInfo> shared = |
1355 Handle<SharedFunctionInfo>::cast(result); | 1365 Handle<SharedFunctionInfo>::cast(result); |
1356 if (!EnsureDebugInfo(shared)) return false; | 1366 if (!EnsureDebugInfo(shared)) return false; |
1357 | 1367 |
1358 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 1368 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
1359 FindBreakablePositions(debug_info, start_position, end_position, | 1369 FindBreakablePositions(debug_info, start_position, end_position, locations); |
1360 BREAK_POSITION_ALIGNED, positions); | |
1361 return true; | 1370 return true; |
1362 } | 1371 } |
1363 | 1372 |
1364 while (true) { | 1373 while (true) { |
1365 HandleScope scope(isolate_); | 1374 HandleScope scope(isolate_); |
1366 List<Handle<SharedFunctionInfo>> candidates; | 1375 List<Handle<SharedFunctionInfo>> candidates; |
1367 SharedFunctionInfo::ScriptIterator iterator(script); | 1376 SharedFunctionInfo::ScriptIterator iterator(script); |
1368 for (SharedFunctionInfo* info = iterator.Next(); info != nullptr; | 1377 for (SharedFunctionInfo* info = iterator.Next(); info != nullptr; |
1369 info = iterator.Next()) { | 1378 info = iterator.Next()) { |
1370 if (info->end_position() < start_position || | 1379 if (info->end_position() < start_position || |
(...skipping 17 matching lines...) Expand all Loading... |
1388 } | 1397 } |
1389 } | 1398 } |
1390 if (!EnsureDebugInfo(candidates[i])) return false; | 1399 if (!EnsureDebugInfo(candidates[i])) return false; |
1391 } | 1400 } |
1392 if (was_compiled) continue; | 1401 if (was_compiled) continue; |
1393 | 1402 |
1394 for (int i = 0; i < candidates.length(); ++i) { | 1403 for (int i = 0; i < candidates.length(); ++i) { |
1395 CHECK(candidates[i]->HasDebugInfo()); | 1404 CHECK(candidates[i]->HasDebugInfo()); |
1396 Handle<DebugInfo> debug_info(candidates[i]->GetDebugInfo()); | 1405 Handle<DebugInfo> debug_info(candidates[i]->GetDebugInfo()); |
1397 FindBreakablePositions(debug_info, start_position, end_position, | 1406 FindBreakablePositions(debug_info, start_position, end_position, |
1398 BREAK_POSITION_ALIGNED, positions); | 1407 locations); |
1399 } | 1408 } |
1400 return true; | 1409 return true; |
1401 } | 1410 } |
1402 UNREACHABLE(); | 1411 UNREACHABLE(); |
1403 return false; | 1412 return false; |
1404 } | 1413 } |
1405 | 1414 |
1406 void Debug::RecordGenerator(Handle<JSGeneratorObject> generator_object) { | 1415 void Debug::RecordGenerator(Handle<JSGeneratorObject> generator_object) { |
1407 if (last_step_action() <= StepOut) return; | 1416 if (last_step_action() <= StepOut) return; |
1408 | 1417 |
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2426 isolate_->Throw(*isolate_->factory()->NewEvalError( | 2435 isolate_->Throw(*isolate_->factory()->NewEvalError( |
2427 MessageTemplate::kNoSideEffectDebugEvaluate)); | 2436 MessageTemplate::kNoSideEffectDebugEvaluate)); |
2428 } | 2437 } |
2429 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_); | 2438 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_); |
2430 isolate_->debug()->UpdateHookOnFunctionCall(); | 2439 isolate_->debug()->UpdateHookOnFunctionCall(); |
2431 isolate_->debug()->side_effect_check_failed_ = false; | 2440 isolate_->debug()->side_effect_check_failed_ = false; |
2432 } | 2441 } |
2433 | 2442 |
2434 } // namespace internal | 2443 } // namespace internal |
2435 } // namespace v8 | 2444 } // namespace v8 |
OLD | NEW |