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 388 matching lines...) Loading... |
399 | 399 |
400 // Threading support. | 400 // Threading support. |
401 void Debug::ThreadInit() { | 401 void Debug::ThreadInit() { |
402 thread_local_.break_count_ = 0; | 402 thread_local_.break_count_ = 0; |
403 thread_local_.break_id_ = 0; | 403 thread_local_.break_id_ = 0; |
404 thread_local_.break_frame_id_ = StackFrame::NO_ID; | 404 thread_local_.break_frame_id_ = StackFrame::NO_ID; |
405 thread_local_.last_step_action_ = StepNone; | 405 thread_local_.last_step_action_ = StepNone; |
406 thread_local_.last_statement_position_ = kNoSourcePosition; | 406 thread_local_.last_statement_position_ = kNoSourcePosition; |
407 thread_local_.last_fp_ = 0; | 407 thread_local_.last_fp_ = 0; |
408 thread_local_.target_fp_ = 0; | 408 thread_local_.target_fp_ = 0; |
409 thread_local_.return_value_ = Handle<Object>(); | 409 thread_local_.return_value_ = Smi::kZero; |
410 thread_local_.async_task_count_ = 0; | 410 thread_local_.async_task_count_ = 0; |
411 clear_suspended_generator(); | 411 clear_suspended_generator(); |
412 // TODO(isolates): frames_are_dropped_? | 412 thread_local_.new_fp_ = nullptr; |
413 base::NoBarrier_Store(&thread_local_.current_debug_scope_, | 413 base::NoBarrier_Store(&thread_local_.current_debug_scope_, |
414 static_cast<base::AtomicWord>(0)); | 414 static_cast<base::AtomicWord>(0)); |
415 UpdateHookOnFunctionCall(); | 415 UpdateHookOnFunctionCall(); |
416 } | 416 } |
417 | 417 |
418 | 418 |
419 char* Debug::ArchiveDebug(char* storage) { | 419 char* Debug::ArchiveDebug(char* storage) { |
420 // Simply reset state. Don't archive anything. | 420 // Simply reset state. Don't archive anything. |
421 ThreadInit(); | 421 ThreadInit(); |
422 return storage + ArchiveSpacePerThread(); | 422 return storage + ArchiveSpacePerThread(); |
423 } | 423 } |
424 | 424 |
425 | 425 |
426 char* Debug::RestoreDebug(char* storage) { | 426 char* Debug::RestoreDebug(char* storage) { |
427 // Simply reset state. Don't restore anything. | 427 // Simply reset state. Don't restore anything. |
428 ThreadInit(); | 428 ThreadInit(); |
429 return storage + ArchiveSpacePerThread(); | 429 return storage + ArchiveSpacePerThread(); |
430 } | 430 } |
431 | 431 |
432 int Debug::ArchiveSpacePerThread() { return 0; } | 432 int Debug::ArchiveSpacePerThread() { return 0; } |
433 | 433 |
434 void Debug::Iterate(ObjectVisitor* v) { | 434 void Debug::Iterate(ObjectVisitor* v) { |
| 435 v->VisitPointer(&thread_local_.return_value_); |
435 v->VisitPointer(&thread_local_.suspended_generator_); | 436 v->VisitPointer(&thread_local_.suspended_generator_); |
436 } | 437 } |
437 | 438 |
438 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { | 439 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { |
439 // Globalize the request debug info object and make it weak. | 440 // Globalize the request debug info object and make it weak. |
440 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); | 441 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); |
441 debug_info_ = | 442 debug_info_ = |
442 Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location(); | 443 Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location(); |
443 } | 444 } |
444 | 445 |
(...skipping 1131 matching lines...) Loading... |
1576 return; | 1577 return; |
1577 } | 1578 } |
1578 // Move to next in list. | 1579 // Move to next in list. |
1579 prev = current; | 1580 prev = current; |
1580 current = current->next(); | 1581 current = current->next(); |
1581 } | 1582 } |
1582 | 1583 |
1583 UNREACHABLE(); | 1584 UNREACHABLE(); |
1584 } | 1585 } |
1585 | 1586 |
1586 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { | |
1587 after_break_target_ = NULL; | |
1588 if (!LiveEdit::SetAfterBreakTarget(this)) { | |
1589 // Continue just after the slot. | |
1590 after_break_target_ = frame->pc(); | |
1591 } | |
1592 } | |
1593 | |
1594 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { | 1587 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { |
1595 HandleScope scope(isolate_); | 1588 HandleScope scope(isolate_); |
1596 | 1589 |
1597 // With no debug info there are no break points, so we can't be at a return. | 1590 // With no debug info there are no break points, so we can't be at a return. |
1598 if (!frame->function()->shared()->HasDebugInfo()) return false; | 1591 if (!frame->function()->shared()->HasDebugInfo()) return false; |
1599 | 1592 |
1600 DCHECK(!frame->is_optimized()); | 1593 DCHECK(!frame->is_optimized()); |
1601 BreakLocation location = BreakLocation::FromFrame(frame); | 1594 BreakLocation location = BreakLocation::FromFrame(frame); |
1602 return location.IsReturn() || location.IsTailCall(); | 1595 return location.IsReturn() || location.IsTailCall(); |
1603 } | 1596 } |
1604 | 1597 |
1605 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, | 1598 void Debug::UpdateBreakFrameId() { |
1606 LiveEditFrameDropMode mode) { | 1599 if (thread_local_.new_fp_ == nullptr) return; |
1607 if (mode != LIVE_EDIT_CURRENTLY_SET_MODE) { | 1600 StackTraceFrameIterator it(isolate_); |
1608 thread_local_.frame_drop_mode_ = mode; | 1601 thread_local_.break_frame_id_ = StackFrame::NO_ID; |
| 1602 for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) { |
| 1603 if (it.frame()->fp() > thread_local_.new_fp_) { |
| 1604 thread_local_.break_frame_id_ = it.frame()->id(); |
| 1605 return; |
| 1606 } |
1609 } | 1607 } |
1610 thread_local_.break_frame_id_ = new_break_frame_id; | |
1611 } | 1608 } |
1612 | 1609 |
1613 | 1610 |
1614 bool Debug::IsDebugGlobal(JSGlobalObject* global) { | 1611 bool Debug::IsDebugGlobal(JSGlobalObject* global) { |
1615 return is_loaded() && global == debug_context()->global_object(); | 1612 return is_loaded() && global == debug_context()->global_object(); |
1616 } | 1613 } |
1617 | 1614 |
1618 | 1615 |
1619 void Debug::ClearMirrorCache() { | 1616 void Debug::ClearMirrorCache() { |
1620 PostponeInterruptsScope postpone(isolate_); | 1617 PostponeInterruptsScope postpone(isolate_); |
(...skipping 605 matching lines...) Loading... |
2226 return Execution::Call( | 2223 return Execution::Call( |
2227 isolate_, | 2224 isolate_, |
2228 fun, | 2225 fun, |
2229 Handle<Object>(debug_context()->global_proxy(), isolate_), | 2226 Handle<Object>(debug_context()->global_proxy(), isolate_), |
2230 arraysize(argv), | 2227 arraysize(argv), |
2231 argv); | 2228 argv); |
2232 } | 2229 } |
2233 | 2230 |
2234 | 2231 |
2235 void Debug::HandleDebugBreak() { | 2232 void Debug::HandleDebugBreak() { |
| 2233 // Initialize LiveEdit. |
| 2234 LiveEdit::InitializeThreadLocal(this); |
2236 // Ignore debug break during bootstrapping. | 2235 // Ignore debug break during bootstrapping. |
2237 if (isolate_->bootstrapper()->IsActive()) return; | 2236 if (isolate_->bootstrapper()->IsActive()) return; |
2238 // Just continue if breaks are disabled. | 2237 // Just continue if breaks are disabled. |
2239 if (break_disabled()) return; | 2238 if (break_disabled()) return; |
2240 // Ignore debug break if debugger is not active. | 2239 // Ignore debug break if debugger is not active. |
2241 if (!is_active()) return; | 2240 if (!is_active()) return; |
2242 | 2241 |
2243 StackLimitCheck check(isolate_); | 2242 StackLimitCheck check(isolate_); |
2244 if (check.HasOverflowed()) return; | 2243 if (check.HasOverflowed()) return; |
2245 | 2244 |
(...skipping 85 matching lines...) Loading... |
2331 save_(debug_->isolate_), | 2330 save_(debug_->isolate_), |
2332 no_termination_exceptons_(debug_->isolate_, | 2331 no_termination_exceptons_(debug_->isolate_, |
2333 StackGuard::TERMINATE_EXECUTION) { | 2332 StackGuard::TERMINATE_EXECUTION) { |
2334 // Link recursive debugger entry. | 2333 // Link recursive debugger entry. |
2335 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, | 2334 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, |
2336 reinterpret_cast<base::AtomicWord>(this)); | 2335 reinterpret_cast<base::AtomicWord>(this)); |
2337 | 2336 |
2338 // Store the previous break id, frame id and return value. | 2337 // Store the previous break id, frame id and return value. |
2339 break_id_ = debug_->break_id(); | 2338 break_id_ = debug_->break_id(); |
2340 break_frame_id_ = debug_->break_frame_id(); | 2339 break_frame_id_ = debug_->break_frame_id(); |
2341 return_value_ = debug_->return_value(); | 2340 return_value_ = handle(debug_->return_value(), isolate()); |
2342 | 2341 |
2343 // Create the new break info. If there is no proper frames there is no break | 2342 // Create the new break info. If there is no proper frames there is no break |
2344 // frame id. | 2343 // frame id. |
2345 StackTraceFrameIterator it(isolate()); | 2344 StackTraceFrameIterator it(isolate()); |
2346 bool has_frames = !it.done(); | 2345 bool has_frames = !it.done(); |
2347 // We don't currently support breaking inside wasm framess. | 2346 // We don't currently support breaking inside wasm framess. |
2348 DCHECK(!has_frames || !it.is_wasm()); | 2347 DCHECK(!has_frames || !it.is_wasm()); |
2349 debug_->thread_local_.break_frame_id_ = | 2348 debug_->thread_local_.break_frame_id_ = |
2350 has_frames ? it.frame()->id() : StackFrame::NO_ID; | 2349 has_frames ? it.frame()->id() : StackFrame::NO_ID; |
2351 debug_->SetNextBreakId(); | 2350 debug_->SetNextBreakId(); |
(...skipping 19 matching lines...) Loading... |
2371 if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand(); | 2370 if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand(); |
2372 } | 2371 } |
2373 | 2372 |
2374 // Leaving this debugger entry. | 2373 // Leaving this debugger entry. |
2375 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, | 2374 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, |
2376 reinterpret_cast<base::AtomicWord>(prev_)); | 2375 reinterpret_cast<base::AtomicWord>(prev_)); |
2377 | 2376 |
2378 // Restore to the previous break state. | 2377 // Restore to the previous break state. |
2379 debug_->thread_local_.break_frame_id_ = break_frame_id_; | 2378 debug_->thread_local_.break_frame_id_ = break_frame_id_; |
2380 debug_->thread_local_.break_id_ = break_id_; | 2379 debug_->thread_local_.break_id_ = break_id_; |
2381 debug_->thread_local_.return_value_ = return_value_; | 2380 debug_->thread_local_.return_value_ = *return_value_; |
2382 | 2381 |
2383 debug_->UpdateState(); | 2382 debug_->UpdateState(); |
2384 } | 2383 } |
2385 | 2384 |
2386 bool Debug::PerformSideEffectCheck(Handle<JSFunction> function) { | 2385 bool Debug::PerformSideEffectCheck(Handle<JSFunction> function) { |
2387 DCHECK(isolate_->needs_side_effect_check()); | 2386 DCHECK(isolate_->needs_side_effect_check()); |
2388 DisallowJavascriptExecution no_js(isolate_); | 2387 DisallowJavascriptExecution no_js(isolate_); |
2389 if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) return false; | 2388 if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) return false; |
2390 Deoptimizer::DeoptimizeFunction(*function); | 2389 Deoptimizer::DeoptimizeFunction(*function); |
2391 if (!function->shared()->HasNoSideEffect()) { | 2390 if (!function->shared()->HasNoSideEffect()) { |
(...skipping 256 matching lines...) Loading... |
2648 logger_->DebugEvent("Put", message.text()); | 2647 logger_->DebugEvent("Put", message.text()); |
2649 } | 2648 } |
2650 | 2649 |
2651 void LockingCommandMessageQueue::Clear() { | 2650 void LockingCommandMessageQueue::Clear() { |
2652 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2651 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
2653 queue_.Clear(); | 2652 queue_.Clear(); |
2654 } | 2653 } |
2655 | 2654 |
2656 } // namespace internal | 2655 } // namespace internal |
2657 } // namespace v8 | 2656 } // namespace v8 |
OLD | NEW |